如何在以下代码中实现GetExitCodeProcess?

时间:2010-07-31 09:08:58

标签: delphi

同样在以下代码中,哪个更有效?

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.

3 个答案:

答案 0 :(得分:1)

如果您决定避免使用线程,我建议使用MsgWaitForMultipleObjects,但只在数组中使用您生成的进程句柄。一旦获得WAIT_OBJECT_0的返回值,就可以调用GetExitCodeProcess。

猜测,因为你使用的是具有预先计算长度的Pascal字符串,所以检查长度应该比对空字符串进行比较更有效,但它完全有可能无论如何,编译器可以将一个转换为另一个,如果它足够聪明,可以发现与''的比较。

答案 1 :(得分:1)

您的代码存在一些问题。你明白它做了什么,或者你只是复制并粘贴它?

  1. 如果你想调用GetExitCodeProcess - 只需在你的情况下调用CloseHandle之前调用它:
  2. 您不需要抽取消息,只需调用WaitForSingleObject一段时间(可能在ShellExecute中处理可能的DDE初始化)。
  3. 你检查一下hHandle&lt;&gt; 0表示CloseHandle,但不适用于WaitForSingleObject。无论是两者还是没有。
  4. 使用ShellExInfo.lpParameters := Pointer(theParams);代替if (Length(theParams) <> 0) then ShellExInfo.lpParameters := PChar(theParams);
  5. 使用ShellExInfo.lpVerb := 'runas';代替ShellExInfo.lpVerb := PChar('runas');
  6. 您的参数传递错误:您不仅忽略了所有参数,除了第一个,还没有将参数括在引号中。
  7. 未使用的theHandle: hWnd参数清楚地表明您刚刚抓住了第一段代码,却没有意识到它是如何工作的。
  8. 可能是另一回事,但我已经无聊了......

答案 2 :(得分:-1)

  

另外在下面的代码中,是   效率更高?

“过早优化是万恶之源” - 唐纳德克努特。