Einzelnen Beitrag anzeigen

Fukiszo
(Gast)

n/a Beiträge
 
#16

AW: ShellExecute liefert ERROR_ACCESS_DENIED

  Alt 15. Jan 2018, 12:48
falls das weiterhelfen kann, hier meine funktionen um etwas zu laden/starten:
sorry, ich habs nur in englisch kommentiert.

viel spass damit.

Delphi-Quellcode:
// this is my oldschool Execution function from MS-DOS now "Windownized" ;-)
// Similar as if you would execute anything on Command-Line
// Result will be greater than 31 on success
// if result is 4294967295/$FFFFFFFF than its a general error
// Example: if ExecuteCommandLine('C;\WINDOWS\TEMP\FILENAME.EXE', False) > 31 then Success := True else Success := False;
Function ExecuteCommandLine(const cmdLine: string; const ShowConsole: Boolean): Cardinal;
const
  flags: array [Boolean] of Integer = (SW_HIDE, SW_SHOWNORMAL);
var
  cmdbuffer: array [0..MAX_PATH] of Char;
begin
 Result := Cardinal($FFFFFFFF);
 GetEnvironmentVariable('COMSPEC', cmdBUffer, SizeOf(cmdBuffer));
 StrCat(cmdbuffer, ' /C ');
 StrPCopy(StrEnd(cmdbuffer), cmdLine);
 Result := WinExec(cmdbuffer, flags[ShowConsole]);
end;

// this is my "ShellExecuteEx" implementation
// Example:
// to run something type
// ExecuteShell('C;\Windows\Temp\FileName.exe','Parameters',False,False);
// to run something type and wait that it finish type
// ExecuteShell('C;\Windows\Temp\FileName.exe','-Parameters',False,True);
// ShowConsole should only be activated for Console Programs
// Returned Value is either ErrorCode from ShellExecuteEx or Init/Exit Code from "Executable"
// if result is 4294967295/$FFFFFFFF than its a general error
function ExecuteShell(const Executable, Commands: String; const ShowConsole, DoWait: Boolean): Cardinal;
 var
  ProcessInfo: TShellExecuteInfo;
 begin
  Result := Cardinal($FFFFFFFF);
  FillChar(ProcessInfo, SizeOf(TShellExecuteInfo), #0);
  with ProcessInfo do
  begin
   cbSize:= SizeOf( TShellExecuteInfo );
   fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
   Wnd := GetActiveWindow();
   lpVerb := 'open';
(* lpVerb can be one of this:
    'edit'  Launches an editor and opens the document for editing.
    'explore' Explores the folder specified by lpFile.
    'find' Initiates a search starting from the specified directory.
    'open' Opens the file, folder specified by the lpFile parameter.
    'print' Prints the document file specified by lpFile.
    'properties' Displays the file or folder's properties.*)

   lpFile:= PChar(Executable);
   lpParameters := PChar(Commands);
   lpDirectory := PChar(ExtractFilePath(Executable));
   if ShowConsole then nShow := SW_SHOWNORMAL else nShow := SW_HIDE;
  end;
  if ShellExecuteEx(@ProcessInfo) then
  begin
// if DoWait then WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
   if DoWait then while WaitForSingleObject(ProcessInfo.hProcess, 500) <> WAIT_OBJECT_0 do ProcessMessages;
   if not GetExitCodeProcess(ProcessInfo.hProcess, Result) then Result := Cardinal($FFFFFFFF);
// GetExitCodeProcess(ProcessInfo.hProcess, Result);
   CloseHandle(ProcessInfo.hProcess);
  end
  else
  begin
   Result := GetLastError;
   exit;
  end;
 end;

// this function execute any Associated Program with "Executable" as Input-Filename optional wait that it finish
// give back as Result the Init/Exit Code of Associated Program or Error Code from FindExecutable
// Example: ExecuteAssociated('ReadMe.txt', False, True);
// that would open "ReadMe.txt" in Editor and wait that Editor terminate
// ExecuteAssociated('ReadMe.html', False, False);
// that would open your Internet Browser with "ReadMe.html" and not wait
// ShowConsole should only be activated for Console Programs
// if result is 4294967295/$FFFFFFFF than its a general error
function ExecuteAssociated(const Executable: String; const ShowConsole, DoWait: Boolean): Cardinal;
var
  Prg: string;
  Security : TSecurityAttributes;
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
 begin
  Result := Cardinal($FFFFFFFF);
  SetLength(Prg, MAX_PATH);
  Result := FindExecutable(PChar(Executable), nil, PChar(Prg));
  if Result > 32 then
  begin
   with Security do begin
    nLength := SizeOf(TSecurityAttributes);
    lpSecurityDescriptor := nil;
    bInheritHandle := False;
   end;
   SetLength(Prg, StrLen(PChar(Prg)));
   FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
   with StartupInfo do
   begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    if ShowConsole then wShowWindow := SW_SHOWNORMAL else wShowWindow := SW_HIDE;
   end;
   if CreateProcess(PChar(Prg), PChar(Format('%s %s', [Prg, Executable])), @Security, @Security, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(Executable)), StartupInfo, ProcessInfo) then
   begin
    if DoWait then while WaitForSingleObject(ProcessInfo.hProcess, 500) <> WAIT_OBJECT_0 do ProcessMessages;
// if DoWait then WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    if not GetExitCodeProcess(ProcessInfo.hProcess, Result) then Result := Cardinal($FFFFFFFF);
// GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
   end
   else
    Result := GetLastError;
  end;
 end;

// this function execute any Executable with Commands optional wait that it finish
// give back as Result the Init/Exit Code of Executable or Error Code from CreateProcess
// example:
// to execute a executable type
// ExecuteExe('C:\WINDOWS\TEMP\FILENAME.EXE','Parameters',False,False);
// to execute a executable and wait type
// ExecuteExe('C:\WINDOWS\TEMP\FILENAME.EXE','Parameters',False,True);
// ShowConsole should only be activated for Console Programs
// DoWait will AntiFreeze and Lock your visible GUI
// this way you could still Update Display in your Application (like a text scroller, or any graphic etc)
// SideEffect: All commands that you click/do/set while in DoWait mode,
// will be executed at once when DoWait is finished.
// if result is 4294967295/$FFFFFFFF than its a general error
// Result can be Init/Exit Code of Executable
function ExecuteExe(const Executable: String; Commands: String; const ShowConsole, DoWait: Boolean): Cardinal;
  procedure WaitFor(processHandle: THandle);
  var
    Msg: TMsg;
    ret: DWORD;
  begin
    repeat
      ret := MsgWaitForMultipleObjects(1, { 1 handle to wait on }
              processHandle, { the handle }
              False, { wake on any event }
              INFINITE, { wait without timeout }
              QS_PAINT or { wake on paint messages }
              QS_SENDMESSAGE { or messages from other threads }
             );
      if ret = WAIT_FAILED then Exit; { can do little here }
      if ret = (WAIT_OBJECT_0 + 1) then
      begin
// if Msg.Message = WM_COMMAND then begin Msg.Message := WM_NULL end else
      while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
// while PeekMessage(Msg, 0, WM_NULL, WM_USER, PM_REMOVE) do (* this would total un-freeze = DoWait would not lock GUI *)
          DispatchMessage(Msg);
      end;
    until ret = WAIT_OBJECT_0;
  end; { Waitfor }
var
  Security : TSecurityAttributes;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
 Result := Cardinal($FFFFFFFF);
 if ((Length(Commands) > 1)and(Commands[1]<>' ')) then Commands := ' ' + Commands;
 with Security do begin
   nLength := SizeOf(TSecurityAttributes);
   lpSecurityDescriptor := nil;
   bInheritHandle := False;
 end;
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  if ShowConsole then StartupInfo.wShowWindow := SW_SHOWNORMAL else StartupInfo.wShowWindow := SW_HIDE;
  if CreateProcess(PChar(Executable), PChar(Commands), @Security, @Security, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(Executable)), StartupInfo, ProcessInfo) then
  begin
   if DoWait then WaitFor(ProcessInfo.hProcess);
   if not GetExitCodeProcess(ProcessInfo.hProcess, Result) then Result := Cardinal($FFFFFFFF);
// GetExitCodeProcess(ProcessInfo.hProcess, Result);
// if Result = 0 then Result := STATUS_PENDING;
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
  end
  else
    Result := GetLastError;
end;

// this function will execute a console application
// give all console output back to "Output:PChar" parameter
// give back as Result the ExitCode of "Executable"
// ShowConsole should only be activated if you want to see a blank Console Window aslong Process is running
// WARNING: DO NOT EXECUTE CONSOLE APPLICATIONS THAT NEED KEYBOARD/MOUSE INPUT!!!
// if result is 4294967295/$FFFFFFFF than its a general error
Function ExecuteConsole(const Executable: String; Commands: String; const ShowConsole: Boolean; var Output: PChar): Cardinal;
const
 ReadBuffer = 4000;
var
  Security : TSecurityAttributes;
  ReadPipe,WritePipe : THandle;
  StartupInfo : TStartUpInfo;
  ProcessInfo : TProcessInformation;
  Buffer : Pchar;
  BytesRead : DWord;
  AppRunning : DWord;
begin
 Result := Cardinal($FFFFFFFF);
 if ((Length(Commands) > 1)and(Commands[1]<>' ')) then Commands := ' ' + Commands;
 with Security do begin
  nLength := SizeOf(TSecurityAttributes);
  lpSecurityDescriptor := nil;
  bInheritHandle := True;
 end;
 if CreatePipe (ReadPipe, WritePipe, @Security, 0) then
 begin
  Buffer := AllocMem(ReadBuffer + 1);
  FillChar(StartupInfo,SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.hStdOutput := WritePipe;
  StartupInfo.hStdInput := ReadPipe;
  StartupInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
  if ShowConsole then StartupInfo.wShowWindow := SW_SHOWNORMAL else StartupInfo.wShowWindow := SW_HIDE;
  if CreateProcess(PChar(Executable), PChar(Commands), @Security, @Security, True, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(Executable)), StartupInfo, ProcessInfo) then
  begin
   repeat
    ProcessMessages;
    Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
   until (Apprunning <> WAIT_TIMEOUT);
// if DoWait then while WaitForSingleObject(ProcessInfo.hProcess, 500) <> WAIT_OBJECT_0 do ProcessMessages;
   repeat
    BytesRead := 0;
    ReadFile(ReadPipe,Buffer[0], ReadBuffer, BytesRead,nil);
    Buffer[BytesRead]:= #0;
   OemToChar(Buffer, Output);
   until (BytesRead < ReadBuffer);
   end;
  FreeMem(Buffer);
  if not GetExitCodeProcess(ProcessInfo.hProcess, Result) then Result := Cardinal($FFFFFFFF);
// GetExitCodeProcess(ProcessInfo.hProcess, Cardinal(Result));
  CloseHandle(ReadPipe);
  CloseHandle(WritePipe);
  CloseHandle(ProcessInfo.hThread);
  CloseHandle(ProcessInfo.hProcess);
 end;
end;

Geändert von Fukiszo (15. Jan 2018 um 12:59 Uhr)
  Mit Zitat antworten Zitat