我尝试使用本教程来工作: 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;
每件事似乎都没问题,我没有任何运行时错误 但点击按钮后没有任何事情发生(不要鞋子任何错误,不要添加钥匙到注册)! 我的作品出了问题!?
我的delphi是xe5并且在win 8ul上工作
答案 0 :(得分:2)
首先,我打算将其视为您的程序正在升级运行。如果没有发生,那么就不需要查看任何代码了。你没有另外说,所以让我们在你成功提升的假设下继续前进。
你正在患registry redirector。您的32位进程在64位计算机上运行。因此HKLM\Software
被重定向到32位视图,存储在HKLM\Software\Wow6432Node
。
如果需要,您可以使用KEY_WOW64_64KEY
标志访问64位视图。将其与注册表对象的Access
属性中的标志相结合。
但是,在枚举启动程序时,系统会从注册表的32位和64位视图中读取密钥,因此您无需执行此操作。为了简单和可预测性,我将把32位程序写入32位视图。
您应该删除对CreateKey
的来电。系统会创建该密钥,您可以放心地认为它存在。你不应该使用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位视图,那么就像这样完成:
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可以提供的启用运行时主题清单以外的清单,则需要自己完成所有操作。
在项目选项中指定您要使用自定义清单。那是Project | Options | Application | Runtime themes
下的。将下拉列表设置为使用自定义清单。然后提供清单的文件名。您将要添加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;
最后要说的是,写入此注册表项是一项管理任务。您应该只需要提升一次,而不是每次应用程序启动时。如果您计划仅为此目的要求应用程序的高程,那么您必须重新设计。此管理任务应在主应用程序之外执行。最自然的地方是您的安装程序,用户将接受要求提升。
答案 1 :(得分:2)
您正在将应用路径保存到Run
配置单元的HKEY_LOCAL_MACHINE
键。您应该使用HKEY_CURRENT_USER
配置单元,然后您将不再需要使用UAC提升(除非您的应用正在执行需要管理员权限的其他事项)。