Delphi 运行具有管理员权限的程序以写入注册表

Delphi 运行具有管理员权限的程序以写入注册表,delphi,Delphi,我尝试使用本教程进行工作: 首先创建一个名为uac.manifest的文件,其中包含提供的内容 然后创建124uac.manifest的uac.rc宽度内容 然后将文件复制到delphi program sources文件夹中的program文件夹,并将项目文件更改如下: program Project4; {.$R 'uac.res' 'uac.rc'} // UAC only uses Vcl.Forms, Unit6 in 'Unit6.pas' {Form6}; {$R

我尝试使用本教程进行工作:

首先创建一个名为uac.manifest的文件,其中包含提供的内容 然后创建124uac.manifest的uac.rc宽度内容

然后将文件复制到delphi program sources文件夹中的program文件夹,并将项目文件更改如下:

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
  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;
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;
最后,我把我的注册代码放在表单上

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;
一切似乎都很好,我没有任何运行时错误 但是点击按钮后什么也没发生,不要出错,也不要将密钥添加到注册表!!! 我的作品哪里有问题


我的delphi是xe5,正在处理win 8ul

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

你正遭受着疾病的折磨。您的32位进程正在64位计算机上运行。因此,HKLM\Software被重定向到存储在HKLM\Software\WOW6432节点的32位视图

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

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

应该删除对CreateKey的调用。系统将创建该密钥,您可以安全地假定它存在。你不应该使用Treginile。改用树木学

您的代码应该如下所示:

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
  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;
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;
如果您觉得需要写入64位视图,则按如下方式完成:

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
  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;
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写信

关于您的清单,您只能链接一个。因此,如果您想指定一个清单,而不是IDE可以提供的启用运行时主题清单,那么您需要自己来完成

在项目选项中,指定要使用自定义清单。这在项目|选项|应用程序|运行时主题下。将下拉列表设置为使用自定义清单。然后提供清单的文件名。您需要添加comctl32 v6部件,以确保获得运行时主题。但是现在不要担心。只需集中精力对高程进行排序,注册表代码就能正常工作

您也在默默地忽略任何错误,这些错误确实会使调试变得更加困难。如果您没有提升,那么运行代码是毫无意义的。你知道它一定会失败。但是如果OpenKey失败,您至少可以通过抛出一个错误来更容易地诊断问题


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

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

你正遭受着疾病的折磨。您的32位进程正在64位计算机上运行。因此,HKLM\Software被重定向到存储在HKLM\Software\WOW6432节点的32位视图

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

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

应该删除对CreateKey的调用。系统将创建该密钥,您可以安全地假定它存在。你不应该使用Treginile。改用树木学

您的代码应该如下所示:

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
  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;
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;
如果您觉得需要写入64位视图,则按如下方式完成:

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
  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;
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写信

关于您的清单,您只能链接一个。所以如果你想成为一个 指定IDE可以提供的启用运行时主题清单之外的清单,您需要自己完成

在项目选项中,指定要使用自定义清单。这在项目|选项|应用程序|运行时主题下。将下拉列表设置为使用自定义清单。然后提供清单的文件名。您需要添加comctl32 v6部件,以确保获得运行时主题。但是现在不要担心。只需集中精力对高程进行排序,注册表代码就能正常工作

您也在默默地忽略任何错误,这些错误确实会使调试变得更加困难。如果您没有提升,那么运行代码是毫无意义的。你知道它一定会失败。但是如果OpenKey失败,您至少可以通过抛出一个错误来更容易地诊断问题


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

您正在将应用程序路径保存到HKEY_LOCAL_机器配置单元的运行密钥。您应该使用HKEY_CURRENT_USER配置单元,然后您将不再需要使用UAC elevation,除非您的应用程序正在执行其他需要管理员权限的操作。

您正在将应用程序路径保存到HKEY_LOCAL_机器配置单元的运行密钥。您应该改用HKEY_CURRENT_USER配置单元,然后您将不再需要使用UAC elevation,除非您的应用程序正在执行其他需要管理员权限的操作。

1您不需要调用Reg.CreateKey,但如果您这样做,您应该检查返回值。2如果注册表项不存在,可以通过将True作为第二个参数来创建注册表项。3您不需要做任何测试来找出Reg.OpenKey失败的原因,如果它成功了,那么它只会做一些事情,但如果失败了,则不提供任何信息-使用GetLastError来找出原因。4 3可能会解释为什么会发生任何事情!!!!我想应该说什么都没发生。5你确定你的应用程序中只存在1个清单吗?没有添加版本信息?4-我的意思是不要显示任何错误,不要添加注册表项5-在该教程中也添加了版本信息,当添加{.$R'uac.res''uac.rc'}时,它将编译资源并删除其他资源/清单,我如何删除其他清单!?1-2-3我移除了Reg.CreateKey螺母没有任何更改…1您不需要调用Reg.CreateKey,但是如果您这样做,您应该检查返回值。2如果注册表项不存在,可以通过将True作为第二个参数来创建注册表项。3您不需要做任何测试来找出Reg.OpenKey失败的原因,如果它成功了,那么它只会做一些事情,但如果失败了,则不提供任何信息-使用GetLastError来找出原因。4 3可能会解释为什么会发生任何事情!!!!我想应该说什么都没发生。5你确定你的应用程序中只存在1个清单吗?没有添加版本信息?4-我的意思是不要显示任何错误,不要添加注册表项5-在该教程中也添加了版本信息,当添加{.$R'uac.res''uac.rc'}时,它将编译资源并删除其他资源/清单,我如何删除其他清单!?1-2-3我拆下了Reg.CreateKey螺母没有任何变化…没有。那不好。您现在正在破坏您的注册表。再次阅读我的答案,并阅读我答案中的链接。不要修改密钥。这是正确的。如果你继续这样做,你只会在你的注册表上乱扔垃圾。你需要像我说的那样查看WOW6432节点。你会发现你的价值所在。但大多数情况下你需要慢一点。你能刷新你的浏览器并阅读我的第一段吗。你看到UAC对话了吗?如果不是,那么尝试运行任何代码都是毫无意义的。你知道它会失败的。你需要了解发生了什么。如果我的答案中的代码确实无法编写,那么您就无法运行。这意味着您没有遇到UAC对话框。做这类工作的基本先决条件是了解UAC。如果你没有,那么你应该休息一段时间来获得理解。我想我们没有什么不同的问题。我相信我至少回答了你最初提出的问题。你需要做的就是我在那个帖子上说的。以管理员的身份运行DelphiIDE,当它启动要调试的进程时,它也将以管理员的身份运行。您不能这样做。每次都会显示UAC对话框。你应该做的不是强迫你的应用程序运行。那真是糟糕的做法。使用单独的进程修改注册表。安装程序是理想的。否。那不好。您现在正在破坏您的注册表。再读一遍我的答案,然后说
在我的答案中,d是链接。不要修改密钥。这是正确的。如果你继续这样做,你只会在你的注册表上乱扔垃圾。你需要像我说的那样查看WOW6432节点。你会发现你的价值所在。但大多数情况下你需要慢一点。你能刷新你的浏览器并阅读我的第一段吗。你看到UAC对话了吗?如果不是,那么尝试运行任何代码都是毫无意义的。你知道它会失败的。你需要了解发生了什么。如果我的答案中的代码确实无法编写,那么您就无法运行。这意味着您没有遇到UAC对话框。做这类工作的基本先决条件是了解UAC。如果你没有,那么你应该休息一段时间来获得理解。我想我们没有什么不同的问题。我相信我至少回答了你最初提出的问题。你需要做的就是我在那个帖子上说的。以管理员的身份运行DelphiIDE,当它启动要调试的进程时,它也将以管理员的身份运行。您不能这样做。每次都会显示UAC对话框。你应该做的不是强迫你的应用程序运行。那真是糟糕的做法。使用单独的进程修改注册表。安装程序非常理想。但现在只有一个特定用户登录时,应用程序才会启动。我知道香港中文大学和香港中文大学在这里有不同的含义。但如果应用程序是按用户运行的,那么存储按用户设置是有意义的,这就是HKCU发挥作用的地方。正如我在论坛上所说的,因为这是一项服务,它只在一个帐户和它的管理员上运行,所以如果这个程序只在当前用户帐户上运行就不重要了。但是,我检查了我的注册表,HKCU中没有密钥软件\Microsoft\Windows\CurrentVersion\run,你是说我在添加值之前创建它!?如果它是一个真正的服务,那么您根本不应该使用Run键。将服务配置为“服务自动启动”,然后SCM将在系统启动期间启动它。如果是普通应用程序,则HKCU中确实存在运行密钥,并且始终具有:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run。如果它不存在,则是,创建它。在64位系统上运行的32位应用程序不会对HKCU下的此特定密钥使用Wow6432Node,但对HKLM使用WOW6432Key,因此您必须对HKLM相应地使用key_WOW64_32KEY和key_WOW64_64KEY标志。但现在,只有一个特定用户登录时,应用程序才会启动。我知道香港中文大学和香港中文大学在这里有不同的含义。但如果应用程序是按用户运行的,那么存储按用户设置是有意义的,这就是HKCU发挥作用的地方。正如我在论坛上所说的,因为这是一项服务,它只在一个帐户和它的管理员上运行,所以如果这个程序只在当前用户帐户上运行就不重要了。但是,我检查了我的注册表,HKCU中没有密钥软件\Microsoft\Windows\CurrentVersion\run,你是说我在添加值之前创建它!?如果它是一个真正的服务,那么您根本不应该使用Run键。将服务配置为“服务自动启动”,然后SCM将在系统启动期间启动它。如果是普通应用程序,则HKCU中确实存在运行密钥,并且始终具有:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run。如果它不存在,则是,创建它。在64位系统上运行的32位应用程序对HKCU下的此特定密钥不使用Wow6432Node,但对HKLM使用Wow6432Node,因此您必须相应地对HKLM使用key_WOW64_32KEY和key_WOW64_64KEY标志。