Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   ShellExecuteEx -> Access denied (https://www.delphipraxis.net/179621-shellexecuteex-access-denied.html)

Klaus01 20. Mär 2014 10:36

ShellExecuteEx -> Access denied
 
Hallo,

ich stehe etwas auf dem Schlauch..

Wenn ich mit shellExecute eine bat Datei starten will dann funktioniert das so:
Delphi-Quellcode:
 parameter := format('%s',['einige Parameter']);
 if shellExecute(handle,nil,pchar('start_tool.bat'),pChar(parameter),nil,SW_SHOW) <= 32 then
   begin
     fLogger.addItem(format('start_tool.bat %s',[parameter]),0);
     fLogger.addItem(sysErrorMessage(getLastError),0);
   end;
Die Datei start_tool.bat liegt in gleichen Verzeichnis wie die exe.

Nun möchte ich aber shellExecuteEx verwenden.
Ich möchte die gestartete Datei überwachen.
Delphi-Quellcode:
 parameter := format('%s',['einige Parameter']);
 shellExeInfo.cbSize := sizeOf(TShellExecuteInfo);
 shellExeInfo.Wnd := handle;
 shellExeInfo.lpVerb := 'open';
 shellExeInfo.lpFile := pchar('start_tool.bat');
 shellExeInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
 shellExeInfo.lpParameters := pChar(parameter);
 shellExeInfo.lpDirectory := pChar(extractFileDir(paramStr(0)));
 shellExeInfo.nShow := SW_SHOW;
 if not shellExecuteEx(@shellExeInfo) then
   begin
     fLastError := getLastError;
     fLogger.addItem(sysErrorMessage(fLastError)+' ['+intToStr(fLastError)+']',0);
     fReturnValue := 3;
   end
 else
   begin
     try
       repeat
         waitState := MsgWaitForMultipleObjects(1,shellExeInfo.hProcess,false,INFINITE,QS_ALLINPUT);
         if waitState <> WAIT_OBJECT_0 then
           sleep(250);
       until waitState = WAIT_OBJECT_0;
    finally
      closeHandle(shellExeInfo.hProcess);
    end;
 end;
Nur erhalte ich damit immer die Fehlermeldung "Access denied" ErrorCode 5.
Und ich weiß nicht warum?
Jemand eine Idee?

Grüße
Klaus

Der schöne Günther 20. Mär 2014 10:43

AW: ShellExecuteEx -> Access denied
 
Was mir nur spontan, ohne in die API-Dokumentation zu schauen auffällt ist, dass du bei shellExeInfo zwar die cbSize setzt, aber in den anderen Feldern (die du nicht explizit beschreibst) noch alles mögliche drinsteht.

Ich würde als erstes noch ein
Delphi-Quellcode:
shellExeInfo := Default(TStartupInfo);
einfügen.

Klaus01 20. Mär 2014 10:52

AW: ShellExecuteEx -> Access denied
 
Hallo,

danke für den Hinweis, werde das Record noch nullen.
Fehler ist/war aber ein anderer.

Delphi-Quellcode:
shellExeInfo.cbSize := sizeOf(TShellExecuteInfo);
TShellExecuteInfo war mein Versuch die shellexecuteInfo nachzubilden.
In meinem Record ist dann wohl noch ein Fehler enthalten.

Delphi-Quellcode:
  TDummyUnionName = record
    hIcon: THandle;
    hMonitor: THandle;
  end;

  TShellExecuteInfo = record
    cbSize: cardinal;   //dword
    fMask: cardinal;    //ulong
    hwnd: THandle;
    lpVerb: pChar;
    lpFile: pChar;
    lpParameters: pChar;
    lpDirectory: pChar;
    nShow: Integer;
    hInstApp: THandle;
    lpIDList: pointer;
    lpClass: pChar;
    hkeyClass: byte;
    dwHotKey: cardinal; //dword
    dummyUnionName: TDummyUnionName;
    hProcess: THandle;
  end;
Delphi-Quellcode:
shellExeInfo.cbSize := sizeOf(ExecuteInfo);
So funktioniert es...


Edit:
Wenn man aus dem Record TDummyUnionName ein Union macht,
Delphi-Quellcode:
  TDummyUnionName = record
    case boolean of
      true: (hIcon: THandle);
      false: (hMonitor: THandle);
  end;
dann klappt es auch mit der selbst gebastelten TShellExecuteInfo.

Danke.

Grüße
Klaus

himitsu 20. Mär 2014 15:16

AW: ShellExecuteEx -> Access denied
 
Zitat:

Delphi-Quellcode:
 parameter := format('%s',['einige Parameter']);
 if shellExecute(handle,nil,pchar('start_tool.bat'),pChar(parameter),nil,SW_SHOW) <= 32 then
   begin
     fLogger.addItem(format('start_tool.bat %s',[parameter]),0);
     fLogger.addItem(sysErrorMessage(getLastError),0);
   end;

besser so
Delphi-Quellcode:
 Parameter := Format('%s', ['einige Parameter']);
 if ShellExecute(handle, nil, PChar('start_tool.bat'), PChar(Parameter), nil, SW_SHOW) <= 32 then
   begin
     Err := GetLastError;
     fLogger.AddItem(Format('start_tool.bat %s', [Parameter]), 0);
     fLogger.AddItem(SysErrorMessage(Err), 0);
   end;

// oder

 Parameter := Format('%s', ['einige Parameter']);
 if ShellExecute(handle, nil, PChar('start_tool.bat'), PChar(Parameter), nil, SW_SHOW) <= 32 then
   begin
     Err := SysErrorMessage(GetLastError);
     fLogger.AddItem(Format('start_tool.bat %s', [Parameter]), 0);
     fLogger.AddItem(Err, 0);
   end;
Rate mal was passiert, wenn Format oder fLogger.AddItem den Fehlercode setzen/ändern. :angel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz