Entwickler-Ecke

Windows API - ShellExecute mit Parametern...


zakoon - Di 18.11.08 14:00
Titel: ShellExecute mit Parametern...
Hallo zusammen,

ich würde gerne einen beliebigen Befehl, der in einem String sitzt, über ShellExecute ausführen.

Normalerweise mache ich das in etwas so:

Delphi-Quelltext
1:
ShellExecute(application.handle, 'open', PChar(strCommand), nilnil, SW_SHOWNORMAL);                    

Leider ist es jetzt aber so, dass strCommand nicht nur einfache Befehle (wie z.B 'firefox.exe') beinhalten kann, sondern auch Parameter (wie z.B 'firefox /URL http://www.google.de/search?q=delphi').

Das funktioniert natürlich nicht mehr, da die Parameter ja ShellExecute getrennt übergeben werden müssten.

Mögliche Lösungen, die mir einfallen:
1. winExec benutzen. Funktioniert gut, "kennt" aber leider einige Windows-Befehle nicht (zB. 'msconfig'). Daher hier unbrauchbar.

2. strCommand in Befehl und Parameter parsen. Das ist aber ziemlich kompliziert, da es z.B. keine eindeutigen Indikatoren für den Start des Parameters gibt. " -" kann z.B. auch im Pfad vorkommen, die Endung des Programms kann unterschiedlich sein, oder auch fehlen, etc... Kennt jemand hierfür eine bereits fertige Function/Procedure?

3. Gibts noch etwas anderes?

Viele Grüße, Zak.

Moderiert von user profile iconmatze: Code- durch Delphi-Tags ersetzt


Timosch - Di 18.11.08 14:12

Ich würde bis zum ersten Leerzeichen parsen, schauen, ob die Datei existiert, wenn ja da trennen, wenn nein, bis zum zweiten Leerzeichen usw. Aber eigentlich sollte der Programmname inkl. Pfad ja in Anführungszeichen eingeschlossen sein, wenn er Leerzeichen enthält. Dann wärs ja wesentlich einfacher (einfach von " bis ").
WinExec richtet sich übrigens einfach nach der Umgebungsvariable PATH. Sollte man allerdings generell nicht mehr verwenden, weil es obsolet ist, in zukünftigen Versionen der Win32-API entfällt und z.T. offenbar schon unter Windows XP Probleme macht.


bummi - Di 18.11.08 14:18
Titel: So gehts ...

Delphi-Quelltext
1:
ShellExecute(application.handle, 'open', PChar('"C:\Program Files (x86)\Mozilla Firefox\firefox.exe"'), PCHAR('/URL http://www.google.de/search?q=delphi'), nil, SW_SHOWNORMAL);                    

MfG
Bummi

http://www.explido-software.de

Moderiert von user profile iconmatze: Delphi-Tags hinzugefügt


zakoon - Di 18.11.08 14:33

@Timosch, so leicht is es glaube ich eben nicht! Was ist mit Befehlen wie "msconfig /s", "cmd /k c:" und so weiter? Msconfig.exe liegt nicht mal in ner Path-Variable. Und wenn die Endung vom Programm fehlt, wie z.B. bei "c:\Programm\Mozilla\Firefox /url http://www.google.de"? Dann müsste ich irgendwie abchecken ob firefox.exe, firefox.bat, firefox.cmd, firefox.com etc.... existieren... Dann ist wiederum nicht auszuschließen, dass es Doppeldeutigkeiten gibt:
"c:\Programme\Firefox 3\Firefox /url http://www.google.de" wenn hier im Ordner "Programme" dann eine firefox.exe/ .bat/ .cmd liegt, habe ich z.B. ein Problem.

@Bummi, ich glaube du hast meine Frage nicht richtig gelesen. Oder nur nicht verstanden, was ich gemeint habe?


bummi - Di 18.11.08 14:43
Titel: Sorry war tatsächlich ein Missverständnis
IMHO, kann das zerlegen in Programm und Parameter nicht so schwer sein
Wenn kein führendes " dann erstes Leerzeichen ansonsten nächstes ".?


zakoon - Di 18.11.08 14:44
Titel: Re: Sorry war tatsächlich ein Missverständnis
user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
IMHO, kann das zerlegen in Programm und Parameter nicht so schwer sein
Wenn kein führendes " dann erstes Leerzeichen ansonsten nächstes ".?


Es gibt Ordner und Programmnamen die Leerzeichen enthalten.


zakoon - Di 18.11.08 14:45
Titel: Re: Sorry war tatsächlich ein Missverständnis
jetzt hab ich auch was missverstanden ;-)

die " sind bisher nicht mit im String... vielleicht kann ich das aber einbauen...


Timosch - Di 18.11.08 15:02

user profile iconzakoon hat folgendes geschrieben Zum zitierten Posting springen:
@Timosch, so leicht is es glaube ich eben nicht! Was ist mit Befehlen wie "msconfig /s", "cmd /k c:" und so weiter? Msconfig.exe liegt nicht mal in ner Path-Variable. Und wenn die Endung vom Programm fehlt, wie z.B. bei "c:\Programm\Mozilla\Firefox /url http://www.google.de"? Dann müsste ich irgendwie abchecken ob firefox.exe, firefox.bat, firefox.cmd, firefox.com etc.... existieren... Dann ist wiederum nicht auszuschließen, dass es Doppeldeutigkeiten gibt:
"c:\Programme\Firefox 3\Firefox /url http://www.google.de" wenn hier im Ordner "Programme" dann eine firefox.exe/ .bat/ .cmd liegt, habe ich z.B. ein Problem.

@Bummi, ich glaube du hast meine Frage nicht richtig gelesen. Oder nur nicht verstanden, was ich gemeint habe?

Wenn mehrere Dateien existieren, die unterschiedliche Endungen haben, dann zuerst .com, wenn das nicht existiert, dann *.exe, dann *.bat, dann *.cmd.


zakoon - Di 18.11.08 15:25

Ich habs jetzt mit bummis Lösung gemacht, also zwinge den Anwender dazu ["] bei langen Pfaden zu verwenden. Die Lösung mit dem parsen des Strings, wie Timosch beschreibt, scheint mir unsicher, bzw. sehr aufwendig, wenn man es Ausnahmen-sicher hinbekommen möchte.

Danke euch beiden, für eure Vorschläge!


Wolle92 - Di 18.11.08 16:21

Teile den String einfach vor dem ersten Slash /...
Der darf in Datei-Ordnernamen nicht vorkommen, Pfade nutzen den Backslash \...

Und wenns keinen Slash gibt, gibts auch keine Parameter...


Yogu - Di 18.11.08 17:34

user profile iconWolle92 hat folgendes geschrieben Zum zitierten Posting springen:
Und wenns keinen Slash gibt, gibts auch keine Parameter...

Doch.


Quelltext
1:
firefox yogularm.de                    

Wo ist der Slash? yogularm.de ist ein einfacher Parameter.


Wolle92 - Di 18.11.08 19:56

mhm... doof...
hab ich gar nicht dran gedacht, obwohl ich ja den ping so oft verwende...

wie wärs mit dem ersten leerzeichen nach dem letzten backslash?

OK, gibt noch dateinamen mit leerzeichen...
also folgendes:
Bis zum letzten backslash gehen, dann zum nächsten leerzeichen, prüfen ob die datei mit allen möglichen endungen exisitiert, wenn nicht schon eine mit angegeben ist (einfach checken, ob es 3 zeichen zwischen punkt und ende gibt, und dann, ob diese 3 zeichen eine gültige Programmerweiterung darstellen...
und wenn die datei existiert, dann den rest als parameter nehmen...


zakoon - Do 20.11.08 20:09

user profile iconWolle92 hat folgendes geschrieben Zum zitierten Posting springen:
mhm... doof...
hab ich gar nicht dran gedacht, obwohl ich ja den ping so oft verwende...

wie wärs mit dem ersten leerzeichen nach dem letzten backslash?

OK, gibt noch dateinamen mit leerzeichen...
also folgendes:
Bis zum letzten backslash gehen, dann zum nächsten leerzeichen, prüfen ob die datei mit allen möglichen endungen exisitiert, wenn nicht schon eine mit angegeben ist (einfach checken, ob es 3 zeichen zwischen punkt und ende gibt, und dann, ob diese 3 zeichen eine gültige Programmerweiterung darstellen...
und wenn die datei existiert, dann den rest als parameter nehmen...


Was machst du dann mit Parameter, die mehrere Backslahes beinhalten? "cmd /k /d".
Was wenn im Parameter noch ein Dateipfad übergeben wird, und dannach nochmal ein Backslash folgt? Was ist wenn die Erweiterung beim Programmname fehlt?
Ich sags euch, das ist echt nicht so einfach.


Wolle92 - Do 20.11.08 23:26

du übergibts alle programmparameter in einem einzigen Funktions-Parameter...

das heißt, du musst nur zwischen Programm und "alle Parameter" trennen...

Nur das mit den Backslashes in den Parametern ist doof...
Aber "cmd /k /d" beinhaltet zwei Slashes, ohne Back...


jaenicke - Fr 21.11.08 09:17

Wie wäre es ganz einfach mit CreateProcess [http://msdn.microsoft.com/en-us/library/ms682425.aspx]...
Da kann die gesamte Kommandozeile in einem Stück übergeben werden ohne Abtrennung der Parameter.


kandesbunzler - Mo 24.11.08 14:33

Gibt es hierfür ein einfaches Beispiel? CreateProcess ist doch deutlich komlexer als ShellExecute ...


jaenicke - Mo 24.11.08 17:14

In diesem Thread siehst du die Verwendung, gibt noch viele mehr, vielleicht auch in der Library:
http://www.delphi-forum.de/viewtopic.php?p=532592#532592