2014-02-12 33 views
1

(從大衛赫弗南試圖建議後更新)當心的Windows 8.1註冊表中讀取虛擬化並不適用於64位應用程序

我有一個傳統的Win32本機應用程序(德爾福6)該HKEY_LOCAL_MACHINE下寫入值註冊表\ Software \\鍵。這些值稍後將被幾個其他傳統Win32本機應用程序和一個新的.NET應用程序讀取。 .NET應用程序構建AnyCPU,因此以64位圖像的形式執行。因爲它使用32位應用程序編寫的配置,.NET軟件將其註冊表讀取重定向到Win32 API應用程序實際寫入的Wow6432Node。

沒有任何應用程序正在運行提升。 所有應用程序都是交互式的。 用於運行應用程序的帳戶具有對HKEY_LOCAL_MACHINE \ Software \\註冊表項及其子項的明確「完全控制」。

據我所知,這不是使用註冊表虛擬化,因爲32位應用程序有寫訪問他們寫到HKLM鍵。

此方案在64位Windows 7和64位Windows 8計算機上工作得很好,但在新的Windows 8.1 64位計算機上都不工作。

雖然傳統的Win32應用程序寫入註冊表沒有錯誤,它現在似乎正在虛擬化。這可以通過查看用戶虛擬化註冊表項來確認;我看到裏面所有的書面價值。

當我使用REGEDIT查看HKEY_LOCAL_MACHINE \ Software \\鍵時,我寫的大約一半的鍵只是從HKEY_LOCAL_MACHINE \ Software \\中丟失,但都存在於虛擬化文件夾中。

據我所知,它與32位應用程序寫權限應該沒有虛擬化,但有。更糟的是,當我讀取非虛擬化密鑰時,我看到一些但並非全部寫入虛擬化商店的值。

爲什麼它突然虛擬化寫入,爲什麼當讀取原始密鑰(即虛擬讀取未按預期工作)時讀取不顯示所有虛擬值?

我認爲這必須是一個權限問題,就好像我運行應用程序「作爲管理員」的關鍵都在那裏。然而,運行提升不是允許的最終配置。

更新

我清理了這臺機器上的所有註冊表設置。無論是HKCU下的虛擬商店還是HKLM下的共享區域。然後再次開始,沒有升高。這導致了類似的症狀,但是這次我只能看到HKLM密鑰中的一個密鑰。

我的打算寫一個Win32應用程序來枚舉HKEY_LOCAL_MACHINE \ SOFTWARE \\鍵的情況下,我正被一些REGEDIT.EXE所愚弄,或者在64位操作系統上運行,並且會更新時,是不是做對我來說我有結果。得到它與傳統的32位WinAPI應用程序和新的64位應用程序之間的虛擬化不匹配。詳情請參閱我的回答。

回答

3

註冊表的虛擬化在Windows 8.1中的工作方式與在Vista,Win7和Win8中的工作方式完全相同。沒有任何更改可以解釋您報告的內容。

您是否知道7年前在Vista中引入了虛擬化技術,以幫助無法修改的應用程序在UAC上工作。這個想法是,你修復你的應用程序以瞭解UAC,並停止運行虛擬化。

關於虛擬化的一點是,如果以標準用戶身份運行,應用程序將寫入虛擬商店。但是,如果您執行提升的應用程序,則應用程序將寫入註冊表的共享部分HKLM。從上面的描述看來,您似乎已經運行了應用程序,並且已將值寫入HKLM而不是虛擬商店。

我建議你清理掉這臺機器上的所有註冊表設置。在HKCU下的虛擬商店中以及在HKLM下的共享區域中。然後重新開始你的應用程序,而不是提升。我相信它會像以前的版本一樣工作。

但是,我很驚訝你仍然在嘗試使用虛擬化功能。這是一個幫助無助的柺杖。不要無奈。停止運行虛擬化。遠離虛擬化。

更新

你的問題編輯改變了這種完全。事實上,你並沒有問及Windows 8.1和早期版本之間的差異。您正在Windows 8.1機器上運行一個不同的程序,一個是64位。而64位進程永遠不會虛擬化。

我再次重申我的建議,即虛擬化不會像你這樣使用。依靠這種方式是愚蠢的。

+0

如果我有任何選擇,我不會使用它,但發展需要時間和成本的錢,現在有一點愛花錢來修復「工作」的傳統應用程序。 –

+0

我會嘗試一下這個建議(我們的Windows 8 64位機器上的一切看起來都很好),看看它是否會將事情排序。 –

+2

事情是不行的。只要有人跑高架,一個扳手就會投入工作。您只需寫信給HKCU而不是HKLM即可。 –

0

好吧,我已經到了這個底部。 David Heffernan說得對,過去這些應用程序的運行時間確實讓水域變得非常混亂。

我寫了一個小測試對應用程序的隔離問題(或者說非問題,因爲它原來) 一個Delphi 6的32位的Win32應用程序,列舉了HKEY_LOCAL_MACHINE \ SOFTWARE \\的關鍵,因爲所有其他遺留應用程序做;即忽略密鑰的虛擬化。這看起來好像在HKEY_LOCAL_MACHINE \ Software \\區域中的所有鍵,即使它們實際上已寫入VirtualStore HKLU區域。這就解釋了爲什麼我們所有的舊版應用都很開心。

我還寫了一個簡單的.NET 64位應用程序來測試它如何枚舉HKEY_LOCAL_MACHINE \ Software \\鍵的註冊表。注意到,無論查看模式(32位還是64位)。它確實看到了虛擬註冊表位置中的所有內容。

我的問題是虛擬化的範圍。它的傳統應用程序。 Windows假定任何64位應用程序都不是傳統應用程序,並且正在做正確的事情; 64位應用程序禁用讀取虛擬化;如果你的64位應用程序必須讀取操作系統爲你虛擬化的傳統32位應用程序編寫的值,則必須自己動手。

有關詳細信息,請參閱此MSDN文章;相關的位(我已經錯過了)在題爲「Registry Virtualization Scope

Registry virtualization is disabled for the following: 
•64-bit processes. 

我已經修改了我的新的應用佔的事實,因爲它必須中繼上由傳統的書面設置部分32位應用程序;這些設置可能會被虛擬化,因此它現在會在回退到未虛擬化之前檢查虛擬化註冊表位置。

+1

我回答了你問的問題。 64位應用程序未被虛擬化的這個問題是不同的,而不是問題。記住這個問題是關於8.1的變化。現在,說你上8.1運行不同的程序! –

0

我一直在困擾同一個問題,我沒有使用64位應用程序。我們的應用程序是一個銷售點軟件,它使用註冊表中的所有用戶共用的密鑰來存儲有關業務應用程序的GLOBAL信息。我們繼續進行的方式是,我們將HKLM/software/Store管理密鑰和子密鑰中的寫入權限授予該密鑰,以便應用程序不會虛擬到私人用戶註冊表中。存儲在那裏的財務和配置信息必須可供運行我們軟件的任何用戶使用。

最重要的是,我們使用reg flags命令來設置該鍵和子鍵上的dont_virtualize dont_silent_fail recurse_flag,以警告Windows停止虛擬化此鍵和子鍵。這在Vista和Windows 7上運行良好,但顯然它在Windows 8.1上無法正常工作。顯然我無論是隨機抽取一些密鑰。

所以在我的情況下,我不指望虛擬化使我的程序工作,而是我被它踢的時候,它不應該被搞砸了。我試圖找到永久禁用此虛擬化的方法,因爲我的程序不需要拐杖走路。

附錄: 在尋找可能的解決方案時,我發現如果32位程序具有向Windows解釋其與Vista和Windows 7兼容的程度的清單,則Windows將停止虛擬化常用註冊表項,甚至會生成當用戶沒有適當的權限寫入我們程序的公共註冊表部分時,會出現預期的訪問錯誤。因此,對於已經在該領域的版本,單獨的清單文件將顯然​​解決此問題,並且我們應該在我們的軟件的新版本中嵌入清單。我們仍然會使用reg flags命令來要求Windows不要虛擬化密鑰,並在未授予訪問權限時給出錯誤,因爲它應該總是首先完成。

相關問題