我的問題很簡單,但我發現一個長時間用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. 如何在Eclipse中設置jvm標誌
- 4. 如何在ngCookies中設置httpOnly標誌?
- 5. 如何設置零標誌
- 6. 如何設置FOUND_ROWS標誌?
- 7. 如何在Visual Studio中設置C++編譯器標誌(2015
- 8. 如何在cpp文件中設置編譯標誌(C++)
- 9. 如何設置 - 默認在git中設置標誌?
- 10. 如何在xCode中爲其他目標設置其他C標誌?
- 11. React Native Android - 如何在ToolBarAndroid中設置標誌圖標?
- 12. 如何在Exchange 2007 w/SP2中設置「標記完成」標誌
- 13. 如何在php中通過ajax設置標誌或指標?
- 14. 如何設置HttpOnly和安全標誌設置在apache2.4.6和tomcat
- 15. 原始套接字 - C# - 設置標誌
- 16. 設置不可變的標誌用C
- 17. C位標誌不能被設置
- 18. 如何設置-A標誌screenrc
- 19. 如何設置「其他Link標誌」?
- 20. 如何設置Cookie HTTPOnly標誌?
- 21. PHP-EWS 2010,如何設置IsRead標誌
- 22. 如何使用GTK/GIO設置標誌?
- 23. 如何禁用cookie時設置標誌
- 24. 如何設置標誌(CPP-NETLIB)
- 25. 如何設置該編譯器標誌?
- 26. 如何正確設置標誌
- 27. 如何設置O_NONBLOCKING標誌的Unix
- 28. 如何設置多個標誌xml android
- 29. 如何在SQL語句中的select語句中設置標誌
- 30. 如何在cookie中設置安全標誌在asp.net web api
難道你真的崇尚設置ACL將註冊表鍵HKLM全部每個人都可以訪問該密鑰?對我來說聽起來不太好。 – 2011-03-23 19:00:15
@David - 允許所有用戶修改共享資源不是一個好習慣,不管它看起來如何。那艘船已經駛了。 – 2011-03-23 19:13:41