![]() |
Re: Trennen von Pfad und Parameter
Lest doch bitte die ganze Dokumentation.
Das PSDK hat zu CreateProcess folgendes geschrieben: The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the following order: c:\program.exe files\sub dir\program name c:\program files\sub.exe dir\program name c:\program files\sub dir\program.exe name c:\program files\sub dir\program name.exe |
Re: Trennen von Pfad und Parameter
ungetestet
Delphi-Quellcode:
Für FileExists würde ich aber 'ne Version empfehlen, welche Suchpfade (z.B. aus %PATH%) mit durchtestet und als Standardverzeichnis bei C:\Windows oder doch C:\Windows\System32 (müßte man mal ausprobieren, wo Windows anfängt mit suchen)
Procedure Split(Const S: String; Var Datei, Parameter: String);
Var B: Boolean; i: Integer; Begin B := False; i := 0; Repeat Inc(i); While (i <= Length(S)) and (S[i] <> ' ') or B do Begin If S[i] = '"' Then B := not B; Inc(i); End; Datei := StringReplace(Copy(S, 1, i - 1), '"', '', [rfReplaceAll]); Until FileExists(Datei) or (i > Length(S)); Parameter := Trim(Copy(S, i, Length(S))); End; @Sir Rufo: hast leider geschrieben, wärend ich schrieb und ich hab nich alles gelesen :stupid: Aber Windows läß leider sowas wie C zu ... drum machen es viele noch so ... würden die endlich mal strikt ihre Konventionen durchsetzen, gäb's sowas wie C nicht (OK, 90% der Programme würden nicht mehr laufen) |
Re: Trennen von Pfad und Parameter
Ich habe inzwischen eine Lösung gefunden, wenn auch nur speziell für den UninstallString:
Delphi-Quellcode:
procedure SplitPathAndParameter(Command:string; var Path,Param:string);
const AnzUninstaller=10; const Uninstaller:array[1..AnzUninstaller] of string= ('RUNDLL32.DLL"','RUNDLL32"','MSIEXEC.EXE"','MSIEXEC"','.EXE"', 'RUNDLL32.DLL','RUNDLL32','MSIEXEC.EXE','MSIEXEC','.EXE'); var p,i:integer; begin for i:=1 to AnzUninstaller do begin p:=Pos(Uninstaller[i],UpperCase(Command)); if p>0 then begin Inc(p,Length(Uninstaller[i])); Path:=Copy(Command,1,p-1); Param:=Copy(Command,p+1,Length(Command)-p); Break; end; end; end; |
Re: Trennen von Pfad und Parameter
In diesem Fall greift der Pattern .EXE, der Parameter ist dann leer
|
Re: Trennen von Pfad und Parameter
und ich hab bei einem meiner Programme 'nen Befehlsscript als Uninstaller eingetragen (wird so auch nicht erkannt)
[add] du willst nicht wissen, was passiert, wenn ich dir mal 'nen Verzeichnisnamen unterschmuggl, welcher z.B. MSIEXEC oder .EXE in Pfadnamen hat :angel2: |
Re: Trennen von Pfad und Parameter
ich frage mich, wie Windows den UninstallString ausführt.
Zitat:
Bei der Ausführung per ShellExecute poppt wie gewünscht die UAC auf ... aber ShellExecute will eben den Parameter separat. Hat noch jemand ne Idee für eine elegante Lösung? |
Re: Trennen von Pfad und Parameter
Mit einem "schönerem" FileExists kannst'e eigentlich meine Variante verwenden.
Das FileExists von Delphi sucht nur an genau dem angegebenem Pfad ... aber da in diesem Fall Dateien ohne Pfadangebe auch über Suchpfade wie in %PATH% angegeben gesucht werden, muß da auch entsprechend geprüft werden. Eventuell könnte man auch einfach satt mit FileExists zu prüfen direkt versuchen ShellExecute aufzurufen und bei einem Fehler (ERROR_FILE_NOT_FOUND) den nächsten Durchgang versuchen. Willst du die Trennung erst, um es z.B. irgendwo anzuzeigen, oder willst du es einfach nur direkt aufrufen? (für Letzteres siehe Code)
Delphi-Quellcode:
(einfach so dahingeschrieben und ungetestet)
Function Call(Const S: String): HINSTANCE;
Var B: Boolean; i: Integer; S, Datei, Parameter: String; Begin SetLength(S, GetSystemDirectory(nil, 0) - 1); GetSystemDirectory(PChar(S), Length(S) + 1); SetCurrentDirectory(PChar(S)); B := False; i := 0; Repeat Inc(i); While (i <= Length(S)) and (S[i] <> ' ') or B do Begin If S[i] = '"' Then B := not B; Inc(i); End; Datei := StringReplace(Copy(S, 1, i - 1), '"', '', [rfReplaceAll]); Parameter := Trim(Copy(S, i, Length(S))); Result := ShellExecute(Handle, nil, PChar(Datei), PChar(Parameter), nil, SW_SHOW); Until not (Result in [ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND]) or (i > Length(S)); End; |
Re: Trennen von Pfad und Parameter
Ich habe es inzwischen doch mit CreateProcess geschafft. An CreateProcess kann man ja die ganze Befehlszeile übergeben. Den Parameter setzt man auf nil. Man muss nur beachten, dass man unter Vista die ganze Anwendung elevaten muss, sonst bricht CreateProcess ab. Oder man kapselt das CreateProcess in einer dll (so wie ich es gemacht habe), die dann elevated wird.
|
Re: Trennen von Pfad und Parameter
Liste der Anhänge anzeigen (Anzahl: 1)
na, so ganz doll war die Sache mit CreateProcess dann doch nicht, denn unter Vista (bei einem anderen Vista auch nicht) startet der Prozess im Hintergrund, was natürlich sehr unschön ist.
Wird unter demselben Vista der Prozess mit ShellExecute aufgerufen, erscheint er im Vordergrund und auch die UAC poppt sauber auf. Also nehme ich zum Aufrufen der Deinstallation-Programme doch ShellExecute. Da muss dann doch der Dateiname vom Parameter getrennt werden, was mir aber jetzt dank himitsu sauber gelungen ist. Ich habe es aber dann doch etwas anders gemacht und ganz so einfach war es auch nicht. Aber es funzt. Das ganze Programm habe ich angehängt. Der interessante Teil ist hier:
Delphi-Quellcode:
// Kommandozeile in Dateinamen und Parameter Splitten
procedure SplitFileAndParam(const Commandline:string; var Filename,Param:string); const AnzSuffixe=3; Suffixe:array[1..AnzSuffixe] of string=('com','exe','bat'); var L,Pathes:TStringList; i,j,k,p:integer; FilenameConcat,FilenamePath,FilenameSuffix:string; Found:boolean; begin // Commandline an Leerzeichen splitten L:=Split(CommandLine,' ',true,false); // Pfadvariable auslesen und bei ; splitten Pathes:=Split(GetEnvironmentVariable('PATH'),';',true,false); Pathes.Insert(0,''); // Dateiname Stueck fuer Stueck wieder zusammensetzen bis er existiert Filename:=''; Found:=false; for i:=0 to L.Count-1 do if not Found then begin FilenameConcat:=RemoveQuotes(Trim(FilenameConcat+' '+L[i])); // Existiert die bis jetzt zusammengesetzte Datei? if FileExists(FilenameConcat) then begin Found:=true; Break; end; // mit vorgesetzten Pfaden aus Umgebungsvariablen probieren if not Found and (ExtractFileDrive(FilenameConcat)='') then begin for j:=0 to Pathes.Count-1 do if not Found then begin FilenamePath:=AddBacklash(Trim(Pathes[j]))+FilenameConcat; if FileExists(FilenamePath) then begin Found:=true; Break; end; // Falls nicht, mit angefuegter Endung COM,EXE,BAT probieren if not Found and (ExtractFileExt(FilenamePath)='') then begin for k:=1 to AnzSuffixe do begin FilenameSuffix:=FilenamePath+'.'+Suffixe[k]; if FileExists(FilenameSuffix) then begin Found:=true; Break; end; end; end; end; end; end; if Found then begin p:=Pos(FilenameConcat,Commandline)+Length(FilenameConcat); while (Copy(Commandline,p,1)<>' ') and (p<Length(CommandLine)) do Inc(p); Filename:=Trim(Copy(CommandLine,1,p)); Param:=Trim(Copy(CommandLine,p+1,Length(CommandLine))); end else begin Filename:=''; Param:=''; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:51 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