同样在以下代码中,哪个更有效?
if(Length(ParamStr(1))<> 0)然后
或
if(ParamStr(1)<>'')然后
{$A8,B-,C-,D-,E-,F-,G+,H+,I-,J-,K-,L-,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V-,W-,X+,Y-,Z1}
program LaunchUAC;
uses
Windows, ShellAPI;
{$R 'MANIFEST.RES'}
(*
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (c) eyeClaxton Software (www.eyeclaxton.com) -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
processorArchitecture="x86"
version="1.0.0.0"
name="eyeClaxton.asInvoker.LaunchUAC" type="win32" />
<description>asInvoker LaunchUAC</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="x86"/>
</dependentAssembly>
</dependency>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
*)
function IsMinimumVista(): Boolean;
var
OSVerInfo: TOSVersionInfo;
begin
OSVerInfo.dwOSVersionInfoSize := SizeOf(OSVerInfo);
Result := Windows.GetVersionEx(OSVerInfo) and (OSVerInfo.dwMajorVersion > 5);
end;
procedure RunAsAdmin(theHandle: hWnd; theFilename: string;
theParams: string; theShow: Integer; bWaitFor: Boolean = True);
var
ShellExInfo: TShellExecuteInfo;
hHandle: DWORD;
Msg: TMsg;
MsgResult: LongBool;
begin
Windows.ZeroMemory(@ShellExInfo, SizeOf(ShellExInfo));
ShellExInfo.cbSize := SizeOf(TShellExecuteInfo);
ShellExInfo.Wnd := theHandle;
ShellExInfo.fMask := SEE_MASK_FLAG_DDEWAIT;
if bWaitFor then
ShellExInfo.fMask := ShellExInfo.fMask or SEE_MASK_NOCLOSEPROCESS;
if (Launch.IsMinimumVista()) then
ShellExInfo.lpVerb := PChar('runas');
ShellExInfo.lpFile := PChar(theFilename);
if (Length(theParams) <> 0) then
ShellExInfo.lpParameters := PChar(theParams);
ShellExInfo.nShow := theShow;
hHandle := 0;
if ShellAPI.ShellExecuteEx(@ShellExInfo) then
try
hHandle := ShellExInfo.hProcess;
if bWaitFor then
begin
while (Windows.WaitForSingleObject(hHandle, 50) <> WAIT_OBJECT_0) do
repeat
MsgResult := PeekMessage(Msg, ShellExInfo.Wnd, 0, 0, PM_REMOVE);
if MsgResult then
begin
Windows.TranslateMessage(Msg);
Windows.DispatchMessage(Msg);
end;
until (not (MsgResult));
end;
finally
if (hHandle <> 0) then
Windows.CloseHandle(hHandle);
end;
end;
begin
if (Length(ParamStr(1)) <> 0) then
Launch.RunAsAdmin(0, ParamStr(1), ParamStr(2), SW_SHOWNORMAL)
else
Windows.MessageBeep(MB_ICONERROR);
end.
答案 0 :(得分:1)
如果您决定避免使用线程,我建议使用MsgWaitForMultipleObjects,但只在数组中使用您生成的进程句柄。一旦获得WAIT_OBJECT_0的返回值,就可以调用GetExitCodeProcess。
猜测,因为你使用的是具有预先计算长度的Pascal字符串,所以检查长度应该比对空字符串进行比较更有效,但它完全有可能无论如何,编译器可以将一个转换为另一个,如果它足够聪明,可以发现与''的比较。
答案 1 :(得分:1)
您的代码存在一些问题。你明白它做了什么,或者你只是复制并粘贴它?
ShellExInfo.lpParameters := Pointer(theParams);
代替if (Length(theParams) <> 0) then ShellExInfo.lpParameters := PChar(theParams);
。ShellExInfo.lpVerb := 'runas';
代替ShellExInfo.lpVerb := PChar('runas');
。theHandle: hWnd
参数清楚地表明您刚刚抓住了第一段代码,却没有意识到它是如何工作的。答案 2 :(得分:-1)
另外在下面的代码中,是 效率更高?
“过早优化是万恶之源” - 唐纳德克努特。