6

我正在使用 Visual Studio 2010,我正在编写一个程序,该程序需要在下设置(和读取)新的注册表值HKLM\Software\myapp

该程序是基于 .NET 2.0 的,目前它在 Windows 7 64 位上运行。这是我的 ocde:

RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey  = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);     

我在运行 Visual Studio 2010 时遇到的问题是它将运行应用程序但以我的身份登录,我是本地管理员组的用户和成员.. 但是我无法创建密钥(尽管我是本地管理员组的一部分,谁有权这样做)。我也不知道如何登录(但它也不是我想要的,从那时起我会将 Adminuser 和密码放入代码中,我已经是管理员了??那为什么??)

如果这根本不可能,是否有创建注册表项的选项?

不知何故将它们添加到项目中??..我在这里有点困惑。

4

6 回答 6

10

仅仅因为您以管理员身份运行(或使用具有管理权限的帐户)并不意味着这些管理权限始终有效。这是一种安全措施,可防止恶意软件利用一直以管理权限愚蠢地使用计算机的用户。

要使用您的管理权限,您需要提升流程。有两种方法可以做到这一点:

  1. 使用清单表明您的应用程序需要管理权限,因此在启动时需要提升。

    这意味着您的应用程序将始终运行提升,并且只应在您的应用程序需要时使用。例如,Windows 注册表编辑器 (RegEdit) 就是这样做的,因为如果没有管理权限,您几乎无能为力。

    在 MSDN上或在我的回答中查找有关如何完成此操作的信息。基本上,您只想将以下行添加到清单中:

    <requestedExecutionLevel level="requireAdministrator" />
    
  2. 如果您只需要某些任务的管理权限(即,将特定设置保存到注册表)并且您的应用程序的其余部分不需要它,您应该启动一个新的提升进程来执行此操作。没有办法暂时提升当前进程,因此您实际上需要分拆一个新进程。

    这种方法的优点是您的应用程序不必一直以管理权限运行(这提高了安全性),并且没有管理权限的用户仍然可以运行您的应用程序来执行其他所有操作(即,除了需要提升的一两个任务之外的所有任务)。

    您分离出一个单独的进程,该进程仅包含使用类写入注册表所需的逻辑,并使用动词Process请求此进程的提升。runas有关详细信息,请参阅此问题。我还写了一个答案,提供了如何从 C# 完成此任务的完整描述,包括示例代码。

当然,正如其他答案所提到的,您的应用程序的设计更有可能是不正确的。Windows 安全模型的整个逻辑是常规应用程序不需要管理权限。他们不需要写入注册表或做其他可能危及机器的事情。如果您需要保留设置,我是否可以建议其他两种可能的方法:

  1. 认识到 Windows 确实是一个多用户操作系统并仅为当前用户编写设置。无论如何,这很有意义,因为不同的用户通常有不同的设置和偏好。而不是HKEY_LOCAL_MACHINE注册表的分支(需要管理权限才能访问),您可能希望使用HKEY_CURRENT_USER. 将第一行代码更改为:

     RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey("Software", true);
    
  2. 通过使用 .NET 中内置的逻辑来保存应用程序的设置,完全跳过了写入注册表的所有麻烦和复杂性。开始阅读此处、此处MSDN上的答案以了解如何做到这一点。我会说这是迄今为止你最好的选择。不要自己编写复杂的代码来做您使用的框架已经内置支持轻松完成的事情。

于 2013-03-31T13:05:53.837 回答
3

您的应用程序的设计可能是错误的。标准桌面应用程序不应写入HKEY_LOCAL_MACHINE. 由于 UAC,您需要拥有管理员权限,并在提升的进程中运行才能写入HKLM.

如果您的应用程序确实需要进行更改,HKLM那么请考虑在安装时进行更改,因为安装程序将运行提升。

如果桌面应用程序确实需要写入,HKLM那么它应该考虑将需要运行的应用程序部分分离到一个单独的进程中。否则,用户将非常厌倦必须通过 UAC 对话框才能运行您的应用程序。即使他们没有使用写入HKLM. 如果你强制整个应用程序要求提升,那么标准用户根本无法运行它。

于 2013-03-31T13:03:36.513 回答
2

运行 Visual Studio 时无法在 HKEY_LOCAL_MACHINE 下创建密钥的原因是 Visual Studio 没有作为提升的进程运行。

对于最终用户,应用程序的清单需要表明需要完整的管理员权限。这是有关为 UAC 嵌入清单的文档

如果注册表项不需要在机器上是全局的,请考虑改为写入 HKEY_CURRENT_USER。

于 2013-03-31T13:00:42.583 回答
1

您应该授予可写权限,在方法中键入后添加真实值。

Registry.LocalMachine.CreateSubKey(@"YOURKEY", true);
Registry.LocalMachine.OpenSubKey(@"YOURKEY", true);

您还需要提升权限才能执行此操作,然后您可以创建一个 .manifest 文件并requireAdministrator像这样设置级别:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

注意:在您的代码中:

RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey  = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);

检查对象标签是否正确,您正在使用标签softwareKeyMyKey创建一个对象,但要设置您正在使用另一个标签的值selfPlacingWindowKey

于 2019-05-10T15:12:03.437 回答
0

正在恢复。在您的项目中创建一个 .manifest 文件。给它与可执行文件相同的名称。"name_of_executable.exe.manifest" 最后更改或创建标签:

<requestedExecutionLevel level = "requireAdministrator" uiAccess = "false" />
于 2017-11-03T11:04:50.747 回答
0

前面的答案提到你需要在清单中指定你需要管理员权限才能使用HKLM

您可以通过以下方式创建清单;

  1. 右键单击您的项目,
  2. 打算添加新的
  3. 点击常规
  4. 单击应用程序清单文件
  5. 点击添加
  6. 打开您的清单文件并找到并取消注释该requireAdministrator

可能会让您感到困惑的更细微的事情是Prefer 32bit在您的项目设置中打勾。

这将意味着注册表无法获得所需的访问掩码,并且它会在没有内部异常的情况下静默失败,因为错误处理程序需要相同的访问掩码,因此无法被利用。

您应该避免在注册表的这一部分存储内容,除非您绝对需要跨用户保留设置,注册表也不应该用于存储密码或其他敏感信息,因为即使使用 ACL 也无法可靠地控制访问。

于 2018-05-01T08:01:09.117 回答