我们需要在运行时将一些设置更改为HKEY_LOCAL_MACHINE。
如果需要在运行时提示uac提升,或者我必须启动第二个提升的过程做’脏工作’吗?
解决方法
我会重新启动自己作为提升,通过命令行参数指示什么高架的事你想做。然后,您可以直接跳到相应的表单,或只保存您的HKLM的东西。
function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean; { See Step 3: Redesign for UAC Compatibility (UAC) http://msdn.microsoft.com/en-us/library/bb756922.aspx This code is released into the public domain. No attribution required. } var sei: TShellExecuteInfo; begin ZeroMemory(@sei,SizeOf(sei)); sei.cbSize := SizeOf(TShellExecuteInfo); sei.Wnd := hwnd; sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI; sei.lpVerb := PChar('runas'); sei.lpFile := PChar(Filename); // PAnsiChar; if parameters <> '' then sei.lpParameters := PChar(parameters); // PAnsiChar; sei.nShow := SW_SHOWNORMAL; //Integer; Result := ShellExecuteEx(@sei); end;
另一个Microsoft建议的解决方案是创建一个COM对象的进程(使用特别创建的CoCreateInstanceAsAdmin函数)。我不喜欢这个想法,因为你必须写和注册一个COM对象。
注意:没有“CoCreateInstanceAsAdmin”API调用。它只是一些浮动的代码。这里是Dephi版本我偶然发现。它显然是基于前缀一个类guid字符串与“Elevation:Administrator!new:”前缀的技巧,当正常隐藏代码内部调用CoGetObject:
function CoGetObject(pszName: PWideChar; pBindOptions: PBindOpts3; const iid: TIID; ppv: PPointer): HResult; stdcall; external 'ole32.dll'; procedure CoCreateInstanceAsAdmin(const Handle: HWND; const ClassID,IID: TGuid; PInterface: PPointer); var BindOpts: TBindOpts3; MonikerName: WideString; Res: HRESULT; begin //This code is released into the public domain. No attribution required. ZeroMemory(@BindOpts,Sizeof(TBindOpts3)); BindOpts.cbStruct := Sizeof(TBindOpts3); BindOpts.hwnd := Handle; BindOpts.dwClassContext := CLSCTX_LOCAL_SERVER; MonikerName := 'Elevation:Administrator!new:' + GUIDToString(ClassID); Res := CoGetObject(PWideChar(MonikerName),@BindOpts,IID,PInterface); if Failed(Res) then raise Exception.Create(SysErrorMessage(Res)); end;
另一个问题:如何处理在Windows XP中作为标准用户运行的人员?