delphi - 以管理员权限运行程序以写入注册表

标签 delphi

我尝试使用本教程来工作: https://stackoverflow.com/a/14710803/1149172

首先创建一个名为 uac.manifest 并包含所提供内容的文件 然后创建 uac.rc 宽度内容为 1 24 "uac.manifest"

然后将文件复制到程序文件夹(在delphi程序源文件夹中)并更改项目文件,如下所示:

program Project4;

{.$R 'uac.res' 'uac.rc'} // UAC only

uses
  Vcl.Forms,
  Unit6 in 'Unit6.pas' {Form6};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm6, Form6);
  Application.Run;
end.

最后我把我的注册码放在表格中

procedure AddEntryToRegistry;
var key: string;
     Reg: TRegIniFile;
begin
  key := 'Software\Microsoft\Windows\CurrentVersion\Run';
  Reg := TRegIniFile.Create;
  try
    Reg.RootKey:=HKEY_LOCAL_MACHINE;
    Reg.CreateKey(Key);
    if Reg.OpenKey(Key,False) then Reg.WriteString(key, 'MyApp', 'c:MyApp.exe');
  finally
    Reg.Free;
  end;
end;

一切似乎都很好,我没有任何运行时错误 但点击按钮后什么也没发生(不要出现任何错误,也不要将 key 添加到注册表中)! 我的作品哪里有问题!?

我的delphi是xe5并且正在win 8ul上工作

最佳答案

首先,我将认为您的程序正在提升运行。如果没有发生这种情况,则无需查看任何代码。你没有说别的,所以让我们在你成功提升的假设下继续。

您正在遭受 registry redirector 的困扰。您的 32 位进程正在 64 位计算机上运行。因此,HKLM\Software 被重定向到 32 位 View ,存储在 HKLM\Software\Wow6432Node 中。

如果需要,您可以使用 KEY_WOW64_64KEY 标志来访问 64 位 View 。将其与注册表对象的 Access 属性中的标志结合起来。

但是,系统在枚举启动程序时会从注册表的 32 位和 64 位 View 中读取 key ,因此您无需执行此操作。为了简单性和可预测性,我会将 32 位程序写入 32 位 View 。

您对 CreateKey 的调用应被删除。系统会创建该 key ,您可以放心地假设它存在。并且您不应该使用TRegIniFile。请改用 TRegistry

您的代码应如下所示:

procedure AddEntryToRegistry;
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create(KEY_ALL_ACCESS);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False) then
      Reg.WriteString('MyApp', 'C:\MyApp.exe');
  finally
    Reg.Free;
  end;
end;

如果您觉得需要写入 64 位 View ,那么可以这样完成:

procedure AddEntryToRegistry;
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    Reg.Access := KEY_ALL_ACCESS or KEY_WOW64_64KEY;
    if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False) then
      Reg.WriteString('MyApp', 'C:\MyApp.exe');
  finally
    Reg.Free;
  end;
end;
<小时/>

从您的评论来看,您似乎无法提升。当您的程序启动时缺少 UAC 对话框就表明这种情况正在发生。一旦程序在没有 UAC 对话框的情况下启动,就没有继续下去的意义。如果没有提升,您将不会写信给 HKLM。

关于您的 list ,您只能链接一个。因此,如果您想要指定 IDE 可以提供的启用运行时主题 list 之外的 list ,则需要您自己完成这一切。

在项目选项中指定您要使用自定义 list 。位于 Project | 下选项|应用 |运行时主题。将下拉列表设置为使用自定义 list 。然后提供 list 的文件名。您需要添加 comctl32 v6 部分以确保获得运行时主题。但现在不用担心。只需专注于对海拔进行排序,并使注册表代码正常工作即可。

您还默默地忽略了任何错误,这确实使事情变得更难调试。如果碰巧您没有提升,那么运行代码就毫无意义了。你知道它一定会失败。但是,如果 OpenKey 失败,您至少可以通过抛出错误来更轻松地诊断问题。

procedure AddEntryToRegistry;
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create(KEY_ALL_ACCESS);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if not Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False) then
      raise EMyExceptionClass.Create('Could not open registry key');
    Reg.WriteString('MyApp', 'C:\MyApp.exe');
  finally
    Reg.Free;
  end;
end;
<小时/>

最后要指出的是,写入此注册表项是一项管理任务。您应该只需要一次提升,而不是每次应用程序启动时都需要。如果您计划仅出于此目的要求应用程序加高,那么您必须重新设计。此管理任务应在主应用程序之外执行。最自然的地方是在您的安装程序中,用户会接受要求提升。

关于delphi - 以管理员权限运行程序以写入注册表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22819179/

相关文章:

delphi - 有没有办法在执行 DWScript 两次时保留变量值?

delphi - 只允许字符串中的某些字符

delphi - 组合框:每个项目上都有一个按钮(用于从列表中删除项目)

delphi - 什么是代码页 0?

android - Delphi XE5 REST/Android 客户端 "Session has expired"

java - 当函数没有返回值时,Delphi XE2 是否正确从 Java/Axis2 导入 WSDL?

德尔福: how to disable TWebBrowser security certificate alert?

delphi - 为什么释放 TObjectList 也会删除控件?

delphi - 我如何使用 delphi xe2 ios firemonkey 的 http.get?

delphi - 为什么 Math.Ceil 在参数计算变量值时会给出意想不到的结果?