![]() |
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 ( ![]()
Code:
Nun zum lustigen teil, das funktionniert super manuelle vom Powershell aber ich bekomme es nicht hin mit Delphi.
$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)) 1. Ich habe versucht die Funktionen als Argument zu benutzen:
Delphi-Quellcode:
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!)
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))';
Delphi-Quellcode:
Wie gesagt, das klappt nicht, weil zu lang.
CreateProcess(nil, PChar('Powershell.exe ' + ArgumentString), @Security, @Security, true, CREATE_NEW_CONSOLE, nil, PChar('C:\'), start, ProcessInfo);
2. Hab es mal mit WriteFile und Pipes versucht
Delphi-Quellcode:
Soweit, so gut. Nun hab ich leider weder Input in den PowerShell, noch hab ich ein Resultat mit ReadFile.
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; Könnt Ihr mir bitte helfen das die Procedure Funktionniert ? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz