我的问题很简单,但我发现一个长时间用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