Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi CreateProcess mit Powershell (https://www.delphipraxis.net/189156-createprocess-mit-powershell.html)

DavidKlimas 10. Mai 2016 14:00


CreateProcess mit Powershell
 
Hallo zusammen,

ich hab jetzt einige Tage lang gegrübelt und muss noch doch mal fragen.

Ich habe verschiedene "advertised Shortcuts" in meinem Startmenu und möchte gern die Zieldatei wissen. Das GetPath von iShellLink gibt da leider nur einen falschen Link vom Windows Installer zurück aber es gibt eine Powershell Funktion die das richtige Resultat ausgibt (Siehe Link):

Code:
$lnk = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Adobe\Adobe Acrobat X Pro.lnk"
$WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer
$ShortcutTarget = $WindowsInstaller.GetType().InvokeMember("ShortcutTarget","GetProperty",$null,$WindowsInstaller,$lnk)
$StringData1 = $ShortcutTarget.GetType().InvokeMember("StringData","GetProperty",$null,$ShortcutTarget,1)
$StringData3 = $ShortcutTarget.GetType().InvokeMember("StringData","GetProperty",$null,$ShortcutTarget,3)
$WindowsInstaller.GetType().InvokeMember("ComponentPath","GetProperty",$null,$WindowsInstaller,@($StringData1,$StringData3))
Nun zum lustigen teil, das funktionniert super manuelle vom Powershell aber ich bekomme es nicht hin mit Delphi.

1. Ich habe versucht die Funktionen als Argument zu benutzen:

Delphi-Quellcode:
var
ArgumentString: WideString;
ArgumentString := '$lnk = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Adobe\Adobe Acrobat X Pro.lnk"' + ';' +
                  '$WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer' + ';' +
                  '$ShortcutTarget = $WindowsInstaller.GetType().InvokeMember("ShortcutTarget","GetProperty",$null,$WindowsInstaller,$lnk)' + ';' + 
                  '$StringData1 = $ShortcutTarget.GetType().InvokeMember("StringData","GetProperty",$null,$ShortcutTarget,1)' + ';' + 
                  '$StringData3 = $ShortcutTarget.GetType().InvokeMember("StringData","GetProperty",$null,$ShortcutTarget,3)' + ';' + 
                  '$WindowsInstaller.GetType().InvokeMember("ComponentPath","GetProperty",$null,$WindowsInstaller,@($StringData1,$StringData3))';
Manuelle klappt das mit dem Semikolon super im Powershell aber wenn ich folgendes probiere, scheint das argument nicht vorständig durchgegeben zu werden (zu lang!)

Delphi-Quellcode:
CreateProcess(nil, PChar('Powershell.exe ' + ArgumentString), @Security, @Security, true, CREATE_NEW_CONSOLE, nil, PChar('C:\'), start, ProcessInfo);
Wie gesagt, das klappt nicht, weil zu lang.


2. Hab es mal mit WriteFile und Pipes versucht

Delphi-Quellcode:
var
ArgumentString:         WideString;
Security:               TSecurityAttributes;
PipeRead, PipeWrite:    THandle;
NewPipeIn, NewPipeOut:  THandle;
Start:                  TStartupInfo;
ProcessInfo:            TProcessInformation;
BytesWritten, BytesRead: DWord;
ResultString:           String;
WasOk:                  Boolean;
Buffer:                 array[0..255] of AnsiChar;

Procedure Test
Begin
   with Security do
   begin
     nLength := SizeOf(Security);
     bInheritHandle := True;
     lpSecurityDescriptor := nil;
   end;
   CreatePipe(PipeRead, NewPipeOut, @Security, 0);
   CreatePipe(NewPipeIn, PipeWrite, @Security, 0);
   with start do
   begin
       FillChar(start, SizeOf(start), 0);
       cb := SizeOf(start);
       dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
       wShowWindow := SW_SHOW; //SW_HIDE;
       hStdInput := NewPipeIn;
       hStdOutput := NewPipeOut;
       hStdError := NewPipeOut;
     end;
   ArgumentString := '-NoExit'
   if CreateProcess(nil, PChar('Powershell.exe ' + ArgumentString), @Security, @Security, true, CREATE_NEW_CONSOLE, nil, PChar('C:\'), start, ProcessInfo) then
   Begin
      ArgumentString := '$lnk = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Adobe\Adobe Acrobat X Pro.lnk"' + #13#10
      WriteFile(PipeWrite, ArgumentString[1], length(ArgumentString), BytesWritten, nil);
      ArgumentString := '$WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer' + #13#10
      WriteFile(PipeWrite, ArgumentString[1], length(ArgumentString), BytesWritten, nil);
      ArgumentString := '$ShortcutTarget = $WindowsInstaller.GetType().InvokeMember("ShortcutTarget","GetProperty",$null,$WindowsInstaller,$lnk)' + #13#10
      WriteFile(PipeWrite, ArgumentString[1], length(ArgumentString), BytesWritten, nil);
      ArgumentString := '$StringData1 = $ShortcutTarget.GetType().InvokeMember("StringData","GetProperty",$null,$ShortcutTarget,1)' + #13#10
      WriteFile(PipeWrite, ArgumentString[1], length(ArgumentString), BytesWritten, nil);
      ArgumentString := '$StringData3 = $ShortcutTarget.GetType().InvokeMember("StringData","GetProperty",$null,$ShortcutTarget,3)' + #13#10
      WriteFile(PipeWrite, ArgumentString[1], length(ArgumentString), BytesWritten, nil);
      ArgumentString := '$WindowsInstaller.GetType().InvokeMember("ComponentPath","GetProperty",$null,$WindowsInstaller,@($StringData1,$StringData3))' + #13#10
      WriteFile(PipeWrite, ArgumentString[1], length(ArgumentString), BytesWritten, nil);
     
      ResultString := '';
      repeat
         WasOK := ReadFile(PipeRead, Buffer, 255, BytesRead, nil);
         if BytesRead > 0 then
         begin
            Buffer[BytesRead] := #0;
            ResultString := ResultString + Buffer;
         end;
      until not WasOK or (BytesRead = 0);
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);    
   end;
   CloseHandle(PipeRead);
   CloseHandle(PipeWrite);
   CloseHandle(NewPipeIn);
   CloseHandle(NewPipeOut);
end;
Soweit, so gut. Nun hab ich leider weder Input in den PowerShell, noch hab ich ein Resultat mit ReadFile.

Könnt Ihr mir bitte helfen das die Procedure Funktionniert ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:25 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