我的問題很簡單,但我發現一個長時間用google搜索的答案。
如何將REG_KEY_DONT_VIRTUALIZE
標誌設置爲由我創建的註冊表項(即HKLM\Software\MyApp
)? 我希望我的程序能夠獨立於用戶。每個啓動我的應用的用戶都應該可以訪問位於該位置的相同配置選項)。 更改應用程序清單我可以通過以管理員身份運行程序來禁用註冊表虛擬化,但我希望普通用戶能夠運行該程序並讀取註冊表值。如何在c中設置REG_KEY_DONT_VIRTUALIZE標誌#
1
A
回答
0
如果你不希望你的應用程序被虛擬化,那麼你使用清單來表明這一點。如果你在你的密鑰上使用了REG_KEY_DONT_VIRTUALIZE
,那麼所有的寫操作都會失敗,因爲你的用戶將不能寫訪問HKLM。
如果您希望所有用戶共享配置,那麼您必須將配置存儲在文件而不是註冊表中。註冊表中沒有任何地方適合所有用戶共享,並允許標準用戶寫入訪問權限。
0
這很不清楚,虛擬化僅針對傳統的非UAC兼容程序啓用,並且始終允許讀取。我必須假設寫入是問題所在。例如,使用安裝程序或Regedit.exe更改密鑰的權限,以便每個人都擁有寫入權限。
0
在不更改ACL或添加ACL的情況下,可以通過RegistryView.Registry64
標誌使用RegistryKey.OpenBaseKey
API來確保以編程方式使用的密鑰正在查看註冊表的64位部分。
無論是否爲應用程序啓用註冊表虛擬化,這對於32位應用程序都可以正常工作。
private const string MyRegistryKeyPath = "Software\\My Company\\My App";
private static RegistryKey OpenMyAppRegistryKey(bool requireWriteAccess = false)
{
using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
return requireWriteAccess
? baseKey.CreateSubKey(MyRegistryKeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree)
: baseKey.OpenSubKey(MyRegistryKeyPath, RegistryKeyPermissionCheck.ReadSubTree);
}
}
如果requireWriteAccess
是假的,此方法將返回null
如果指定的鍵不存在。
我還應該指出,這段代碼將需要提升的權限才能打開寫入權限的密鑰。但我相信它可以確保使用以這種方式打開的密鑰的未升級讀取操作只能來自注冊表的64位視圖。
0
迄今爲止,沒有C#或C API來設置註冊表項標誌。
我假設最安全的方法是使用CreateProcess啓動REG.exe命令行工具。
但是,根據記錄,我從this blog它展示瞭如何利用未公開的API另一種方式粘貼一些「C」代碼:
typedef enum _CONTROL_FLAGS {
RegKeyClearFlags = 0,
RegKeyDontVirtualize = 2,
RegKeyDontSilentFail = 4,
RegKeyRecurseFlag = 8
} CONTROL_FLAGS;
typedef struct _KEY_CONTROL_FLAGS_INFORMATION {
ULONG ControlFlags;
} KEY_CONTROL_FLAGS_INFORMATION, *PKEY_CONTROL_FLAGS_INFORMATION;
typedef enum _KEY_SET_INFORMATION_CLASS {
KeyWriteTimeInformation,
KeyWow64FlagsInformation,
KeyControlFlagsInformation,
KeySetVirtualizationInformation,
KeySetDebugInformation,
MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum
} KEY_SET_INFORMATION_CLASS;
NTSYSAPI NTSTATUS NTAPI NtSetInformationKey(
IN HANDLE KeyHandle,
IN KEY_SET_INFORMATION_CLASS InformationClass,
IN PVOID KeyInformationData,
IN ULONG DataLength);
typedef NTSYSAPI NTSTATUS (NTAPI* FuncNtSetInformationKey) (
HANDLE KeyHandle,
KEY_SET_INFORMATION_CLASS InformationClass,
PVOID KeyInformationData,
ULONG DataLength);
BOOL CRegLonMigration::SetDontVirtualizeFlag(LPCTSTR keyPath)
{
FuncNtSetInformationKey ntsik = (FuncNtSetInformationKey)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtSetInformationKey");
KEY_CONTROL_FLAGS_INFORMATION kcfi = {0};
kcfi.ControlFlags = RegKeyDontVirtualize | RegKeyRecurseFlag;
HKEY hKey = NULL;
LSTATUS status;
if (ERROR_SUCCESS == (status = ::RegOpenKeyEx(ROOT_KEY, keyPath, 0, KEY_ALL_ACCESS, &hKey)))
{
NTSTATUS status = ntsik(hKey, KeyControlFlagsInformation, &kcfi, sizeof(KEY_CONTROL_FLAGS_INFORMATION));
RegCloseKey(hKey);
return TRUE;
}
return FALSE;
}
相關問題
- 1. C++設置「標誌」
- 2. 如何在WinGhci中設置標誌,Haskell
- 3. 如何設置FOUND_ROWS標誌?
- 4. 如何在cpp文件中設置編譯標誌(C++)
- 5. 如何設置 - 默認在git中設置標誌?
- 6. 如何在php中通過ajax設置標誌或指標?
- 7. 如何在Exchange 2007 w/SP2中設置「標記完成」標誌
- 8. 如何使用GTK/GIO設置標誌?
- 9. 如何設置標誌(CPP-NETLIB)
- 10. 如何禁用cookie時設置標誌
- 11. 如何設置Cookie HTTPOnly標誌?
- 12. 如何設置該編譯器標誌?
- 13. 如何正確設置標誌
- 14. 如何在cookie中設置安全標誌在asp.net web api
- 15. 如何在SQL語句中的select語句中設置標誌
- 16. 在Eclipse中設置優化標誌CDT
- 17. 無法在ActionBar中設置標誌
- 18. 若要在javascript中設置標誌值
- 19. 在makefile中設置標誌的條件
- 20. 在Armsim中設置進位標誌#
- 21. 未在python-gflags中設置標誌
- 22. 如何設置autotools默認的C++編譯標誌
- 23. 如何設置不分段(IP_DF)標誌使用C
- 24. 標誌如何在C中工作?
- 25. 如何在TYPO3中手動設置已刪除的標誌?
- 26. 如何在java中使用websockets設置TOS標誌
- 27. 如何在QMainWindow中設置多個標誌?
- 28. 如何在THEANORC文件中設置Theano標誌?哪裏?
- 29. 如何在Qt中取消設置標誌?
- 30. 如何在高圖表標誌中設置風格圖像?
難道你真的崇尚設置ACL將註冊表鍵HKLM全部每個人都可以訪問該密鑰?對我來說聽起來不太好。 – 2011-03-23 19:00:15
@David - 允許所有用戶修改共享資源不是一個好習慣,不管它看起來如何。那艘船已經駛了。 – 2011-03-23 19:13:41