为什么我不能使用TRegistry和Delphi在Windows注册表中创建RunOnce条目?

Nic*_*ges 3 delphi runonce

我使用以下代码尝试生成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.
Run Code Online (Sandbox Code Playgroud)

我运行应用程序,然后执行.

但是,没有条目:

HKEY_LOCAL_MACHINE\SOFTWARE \微软\的Windows\CurrentVersion \的RunOnce

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

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

Dav*_*nan 8

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

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel
        level="requireAdministrator"
        uiAccess="false"/>
    </requestedPrivileges>
  </security>
</trustInfo>
Run Code Online (Sandbox Code Playgroud)

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

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

在64位系统上,我认为您应该努力写入HKLM\Software,因此您需要禁用重定向.通过包含KEY_WOW64_64KEYAccess您的TRegistry实例的属性中来执行此操作.

Windows将在处理RunRunOnce密钥时合并注册表的两个视图,但如果您为该特定密钥写入注册表的64位区域,则应用程序将留下更清晰的路径.