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

时间:2011-08-08 15:20:04

标签: 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.

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

但是,没有条目:

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

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

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

2 个答案:

答案 0 :(得分: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属性中来实现此目的。

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

答案 1 :(得分:3)

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

三种可能性:

  1. 请勿使用该密钥并找到其他方法。
  2. Read here. An app manifest可能是要走的路(“使用应用程序清单标记所需权限”一节)。这将在用户启动应用程序时询问用户是否同意。这是简单的方法。
  3. 让用户在没有管理员权限的情况下运行您的应用程序,并将需要它们的代码放在另一个可执仅在用户请求时才按需运行。这是更好的方式。
  4. 添加部分的

    修改

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