2010-07-31 4 views
0

Également dans le code suivant, qui est plus efficace?Comment implémenter GetExitCodeProcess dans le code suivant?

si (Longueur (ParamStr (1)) <> 0) puis

ou

si (ParamStr (1) <> ''), puis

{$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. 
+1

Que voulez-vous dire: "implement"? Pourquoi avez-vous besoin d'implémenter la fonction WinAPI intégrée standard? Vous voulez probablement l'appeler? – Alex

Répondre

1

Si vous êtes Déterminé à éviter les threads, je suggérerais d'utiliser MsgWaitForMultipleObjects mais seulement avoir votre handle de processus généré dans le tableau. Une fois que vous obtenez une valeur de retour de WAIT_OBJECT_0, vous pouvez appeler GetExitCodeProcess. En supposant que vous utilisiez des chaînes Pascal qui ont une longueur pré-calculée, vérifiez la longueur si est plus efficace que de faire une comparaison avec une chaîne vide, mais il est tout à fait possible que le compilateur dans l'autre de toute façon, si c'est assez intelligent pour repérer le comparer contre ''.

+0

Remercions Je vais essayer cela, si (WAIT_OBJECT_0 = Windows.MsgWaitForMultipleObjects (1, hHandle, Faux, INFINI, QS_PAINT ou QS_SENDMESSAGE)) puis Windows.GetExitCodeProcess (hHandle, Résultat); –

1

Il y a quelques problèmes avec votre code. Comprenez-vous ce que cela fait ou copiez-vous simplement & le coller?

  1. Si vous voulez appeler GetExitCodeProcess - il suffit de l'appeler: juste avant d'appeler CloseHandle dans votre cas.
  2. Vous n'avez pas besoin de pomper des messages, appelez simplement WaitForSingleObject pour une période indéfinie (l'initialisation DDE possible est gérée dans ShellExecute).
  3. Vous vérifiez que hHandle <> 0 pour CloseHandle, mais pas pour WaitForSingleObject. Soit le faire pour les deux ou aucun. Utiliser ShellExInfo.lpParameters := Pointer(theParams); au lieu de if (Length(theParams) <> 0) then ShellExInfo.lpParameters := PChar(theParams);.
  4. Utilisez ShellExInfo.lpVerb := 'runas'; au lieu de ShellExInfo.lpVerb := PChar('runas');.
  5. Votre passage de paramètre est erroné: non seulement vous ignorez tous les paramètres, sauf le premier, mais vous ne placez pas non plus de paramètres dans les guillemets.
  6. Inutilisé theHandle: hWnd paramètre est une indication claire que vous venez d'attraper le premier morceau de code, sans se rendre compte comment cela fonctionne.
  7. peut être quelque chose d'autre, mais je me ennuie déjà ...
-1

également dans le code suivant, qui est plus efficace?

"L'optimisation prématurée est la racine de tout mal" - Donald Knuth.

+0

"Celui qui se tient sur les toilettes haut sur le pot." - Confucius –

+0

Citation sélective, une version plus complète: «Les programmeurs perdent énormément de temps à penser ou à se soucier de la vitesse des parties non critiques de leurs programmes, et ces tentatives d'efficacité ont un impact négatif sur le débogage et la maintenance .Nous devrions oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal. Pourtant, nous ne devrions pas laisser passer nos opportunités dans ce 3% critique. Un bon programmeur ne sera pas bercé dans la complaisance par un tel raisonnement, ... ' – EJP

+0

@EJP Wow, pensez-vous vraiment que comparer la chaîne vide à zéro serait un goulot d'étranglement dans ce code? Vraiment? :RÉ – Alex

Questions connexes