3

我正在使用以下代码尝试创建一个 RunOnce 条目:

program RunOnceTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, Registry, Windows;

var
  R: TRegistry;
begin
  try
    WriteLn('Testing RunOnStartup.......');


    R := TRegistry.Create;
    try
      R.RootKey := HKEY_LOCAL_MACHINE;
      R.LazyWrite := False;
      R.OpenKey('Software\Microsoft\Windows\CurrentVersion\RunOnce', True) ;
      R.WriteString('this', 'that') ;
      R.CloseKey;
    finally
      R.free;
    end;

    WriteLn('Test Finished');

    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

我运行应用程序,它执行。

但是,在以下位置没有条目:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

在我的注册表中。我需要管理员权限吗?我还需要做什么?

补充:我应该更好地解释并真正问一个关于我想要做什么的问题。我试图让我的应用程序在启动时自动运行。许多应用程序执行此操作似乎不需要管理员权限。这样做的正常方法是什么?

4

2 回答 2

8

首先,您需要有管理员权限才能在那里写信。大多数情况下,只是安装程序写入此密钥,并且它们通常运行提升。如果这是您想要的方式,请将其添加到您的应用程序清单中:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel
        level="requireAdministrator"
        uiAccess="false"/>
    </requestedPrivileges>
  </security>
</trustInfo>

如果此写入HKLM是从不需要提升的应用程序进行的,那么请考虑将写入分离HKLM到一个单独的进程中,以便只有该注册表项写入需要提升。这是 UAC 的最佳实践。

另一件可能会让您感到困扰的是您的 Delphi 应用程序将是 32 位的,因此会受到注册表重定向的影响。的访问HKLM\Software将被重定向到HKLM\Software\Wow6432Node.

在 64 位系统上,我认为您应该努力写入HKLM\Software,因此您需要禁用重定向。通过包含KEY_WOW64_64KEY在您的实例的Access属性中来做到这一点。TRegistry

RunWindows 将在处理和键时合并注册表的两个视图,RunOnce但如果您为该特定键写入注册表的 64 位区域,您的应用程序将留下更清晰的痕迹。

于 2011-08-08T15:35:26.433 回答
3

是的,修改 HKEY_LOCAL_MACHINE 需要管理员权限。

三种可能:

  1. 不要使用该密钥并找到另一种方法。
  2. 在这里阅读。应用程序清单可能是要走的路(“使用应用程序清单标记所需权限”部分)。这将在用户启动应用程序时征求用户同意。这是最简单的方法。
  3. 让用户在没有管理员权限的情况下运行您的应用程序,并将需要它们的代码放在另一个可执行文件中。按需运行,并且仅在用户请求时运行。这是最好的方式。

编辑添加的部分:

您是否尝试过使用 HKEY_CURRENT_USER 代替?这仅为当前用户运行应用程序,但您不需要具有管理员权限即可写入注册表。

于 2011-08-08T15:29:44.837 回答