Entwickler-Ecke

Dateizugriff - ShellExecute() Probleme !!!


alex_id - Di 25.03.03 05:30
Titel: ShellExecute() Probleme !!!
Hi Leute

Also ich habe folgendes Problem:
ich möchte über ShellExecute() ein anderes Programm mit Parametern starten ohne Parameter funktioniert das ganze !!!

so versuche ich es zu starten :

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
// Auszug aus meinem Prog !!!

procedure TForm1.run(Sender: TObject);
Var
RunFile, path, program, opt : String;

Begin
    path       := ExtractFilePath(ParamStr(0));
    program := 'meinProg.exe'
    opt         := edit1.text;
    RunFile   := path + program + '  ' + opt;
    ShellExecute(0,'open',PChar(RunFile),'','',0);
end;


Wo liegt das Problem ??? :evil:

Alex


Delete - Di 25.03.03 09:30

Die Parameter sind beim Aufruf von ShellExecute gesondert anzugeben. Wenn du dir mal die Syntax des Befehls anschaust:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
HINSTANCE ShellExecute(
    HWND hwnd,
    LPCTSTR lpOperation,
    LPCTSTR lpFile,
    LPCTSTR lpParameters,  // <-- Was´n das? ;o)
    LPCTSTR lpDirectory,
    INT nShowCmd
);

Das steht meines Wissens aber sogar in der uralten Win32-API-Hilfe von Delphi. Mit anderen Worten: hättest du auch rausfinden können. :wink:


alex_id - Di 25.03.03 17:09

ohhh ohh .... verda.... da hab ich schon wieder was übersehen :oops:

danke !!!

Alex


alex_id - Mi 26.03.03 01:39

Hi

ich habe mein Prog jetzt geändert (dank MathiasSimmack)
jedoch komme ich immer noch nicht zu dem gewünschten Erfolg da mein 2. Prog nicht mit den Parametern startet , ohne Parameter geht es !!!
Also immer noch das gleiche Problem !!!

mein ShellExecute sieht jetzt so aus :

Quelltext
1:
ShellExecute(0,'open',PChar(run),PChar(opt),' ',0);                    


Was ist nun mein Problem ?? Wenn ich mein 2. Programm aus der Command line starte funktioniert es !?!?!?

Alex


Delete - Mi 26.03.03 10:50

Evtl. das Leerzeichen im Parameter für das Arbeitsverzeichnis?

Quelltext
1:
...,' ',0);                    

Mach mal

Quelltext
1:
ShellExecute(0,'open',PChar(run),PChar(opt),'',0);                    

draus oder schreib nil rein:

Quelltext
1:
ShellExecute(0,'open',PChar(run),PChar(opt),nil,0);                    


alex_id - Mi 26.03.03 19:00

Hi

Also ich hab das jetzt auch mit "nil" für die Directory Option eingesetzt und es funktioniert immer noch nicht (das Programm wird überhaupt nicht aufgerufen ich hab es noch mal von der Comand line versucht und da funktioniert es wunderbar !!!

Ich weiss einfach nicht mehr weiter :cry:

Alex


foxy - Fr 28.03.03 09:34

ja du must schon eine dirctory haben ... überleg doch ma logisch
dein rpogramm weis ja nicht welche datei , etc. es durch shellexecute starten soll


Quelltext
1:
ShellEecute(Application.Handle,Pchar(Name),nil,PChar(Path),sw_ShowNormal);                    


so habe ich das immer gemacht und es ging wunderbar


Delete - Fr 28.03.03 09:57

Überleg du auch mal logisch, foxy! Im ersten Beitrag von alex heißt es:

Quelltext
1:
2:
3:
4:
path       := ExtractFilePath(ParamStr(0));
program := 'meinProg.exe'
{ ... }
RunFile   := path + program;

Da steckt der Pfad also schon mit drin. Der Parameter "lpDirectory" bezeichnet das Arbeitsverzeichnis. Und das muss nicht zwangsläufig mit dem Verzeichnis des Programms identisch sein. Es könnte sich auch um ein Verzeichnis mit Daten handeln, auf die dein Programm zugreifen soll.

Oder du lässt es einfach leer, und es funktioniert ebenso wunderbar. Warum glaubst du, geht das hier:

Quelltext
1:
ShellExecute(0,'open','explorer.exe',nil,nil,0);                    

Da ist ja überhaupt kein Verzeichnis drin. :shock:


foxy - Fr 28.03.03 11:19

mathias das kann ja schon sein ....
aber er kann doch das mit

meinpro+path weglassen
somit hat er beide werte

ich weis nur nicht so genau was das


Quelltext
1:
RunFile   := path + program + '  ' + opt;                    

hier soll

opt denke ich mal ist doch die pfaderweiterung oder irre ich mich?
aber was soll der leerstring da drin .. ich steig da nich ganz durch :roll:

mom ich hab mir es nomma genau angekuckt .... kann es sein, das du verschiedene ausführungsdateien, nur mit anderem bezeichner hast

also bps: MeinProg 1 ; meinProg 2
deswegen der leerstring und die var opt?


Delete - Fr 28.03.03 14:33

foxy hat folgendes geschrieben:
ich weis nur nicht so genau was das


Quelltext
1:
RunFile   := path + program + '  ' + opt;                    

hier soll

Das hatten wir bereits geklärt. Das war die ursprüngliche Frage: warum startet das Programm nicht, wenn er Parameter angibt. Problem: er hat die Parameter an den Dateinamen gehangen und nicht im lpParameters-Parameter angegeben.


foxy - Fr 28.03.03 15:23

ja ok habs endlich geblickt :rofl:


alex_id - Fr 28.03.03 17:20

Hi Leute !!

Danke für eure Beiträge !!!

Aber wie gesagt ich kann jede *.exe ausführen die ich möchte nur es funktioniert nicht wennich es mit Parametern versuche !!!

Ich hab echt keine Ahnung wo das Problem liegt !!!
Denn wie gesagt wenn ich es von der command line versuche geht es !!

Alex


Delete - Fr 28.03.03 17:54

Wie wäre es denn, wenn du mal die Funktion/Prozedur postest, in der du ShellExecute aufrufst? Falls du dabei Variablen benutzt, die in anderen Prozeduren gefüllt werden, dann wäre ein Hinweis nicht übel, dass sich in diesen Variablen auch die richtigen Datei- und/oder Pfadnamen befinden (notfalls mit Code belegen).

Das ist für die Lesenden sinnvoller als wenn wir jetzt (ohne Codeauszug!) anfangen zu raten, wo dein Problem liegen könnte.


alex_id - Fr 28.03.03 18:29

So hab jetzt noch mal meinen Code gepostet.
kleiner Hinweis, ich habe jetzt das ganze mit WinZip Command line versucht (ist im Code vermerkt);


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
procedure TForm1.FormCreate(Sender: TObject);
var IniFile : TIniFile;
    MDate   : TDateTime;
    path, s, d, y, m, mc, opt, run : String;
begin
   try
   path := ExtractFilePath(ParamStr(0));
   IniFile:=TInifile.Create(path + 'set.ini');
   Source := IniFile.ReadString('Folder','Source','');
   Target := IniFile.ReadString('Folder','Target','');
   Label3.Caption := Source;
   Label4.Caption := Target;
   finally
   IniFile.Free;
   end;
   label5.Caption:='processing . . . ';
   MDate := date;
   Label6.Caption := DateToStr(Mdate);
   mc := IntToStr(monthof(MDate));
   m  := mc;
   if (StrToInt(mc) < 10) then m:= '0'+ mc;
   d := IntToStr(dayof(MDate));
   y := IntToStr(yearof(MDate));
   s:= 'NW-'+ m + '-' + d + '-' + y + '.zip';
   Label6.Caption:=s;
//   target := '"' + target + s + '"';       Parameter mit "
//   source := '"' + source + '\*.*"';     Parameter mit "
   target := target + s;                   // Parameter ohne "
   source := source + '\*.*';           // Parameter ohne "
   opt := ' ' + Target + ' ' + source;
   run := 'wzzip.exe';                    // Test mit WinZip Command Line
//   ShowMessage(run+opt);
   ShellExecute(0,'open',PChar(run),PChar(opt),nil,0);
   Application.Terminate;
end;

danke

Alex


Delete - Fr 28.03.03 23:51


Quelltext
1:
2:
run := 'wzzip.exe';
ShellExecute(0,'open',PChar(run),PChar(opt),nil,0);

Tja. In deinem ersten Posting machst du´s noch richtig, dann lege ich mich deinetwegen mit foxy an ... und was sehen meine müden Augen? Du gibst kein Verzeichnis an.
Also, den Pfad, in dem sich WinZip befindet, ergänzen! Entweder im Parameter "run" (wie in deinem allerersten Posting) oder mit der Methode über den lpDirectory-Parameter, die foxy vorgeschlagen hat.

Und heißt die Exe von WinZip wirklich "wzzip.exe" (mit zwei Z)?


alex_id - Sa 29.03.03 00:10

Hi !!!

Sorry ... das mit dem path hab ich beim testen mal rausgenommen gehabt aber auch wenn ich es rein nehme gibt es keine änderung !!
bitte ersetzt diese Zeile durch :

Quelltext
1:
ShellExecute(0,nil,PChar(run),PChar(opt),PChar(path),0);                    


und die datei heisst wirklich 'wzzip.exe' und ist im selben verzeichnis und ist die command line erweiterung für Winzip !!!

Alex


Delete - Sa 29.03.03 10:40

Ich habe mal deine Prozedur in Ordnung gebracht und ein paar unnötige Variablen rausgeschmissen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.FormCreate(Sender: TObject);
var
  Source,
  Target  : string;
  IniFile : TIniFile;
  path,
  s,
  run     : String;
begin
  path     := ExtractFilePath(ParamStr(0));

Wenn man auf eine INI-Datei zugreifen will, dann wird diese vor dem try/finally-Block initialisiert:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  IniFile  := TInifile.Create(path + 'set.ini');
  try
    Source := IniFile.ReadString('Folder','Source','');
    Target := IniFile.ReadString('Folder','Target','');
  finally
    IniFile.Free;
  end;

  Label3.Caption := Source;
  Label4.Caption := Target;
  Label5.Caption :='processing . . . ';

Auf die ganzen Datumsvariablen kannst du verzichten, wenn du mit FormatDateTime das Datum gleich in die gewünschte Form bringst. Du musst nur die Textstellen, die unverändert bleiben sollen (also das NW, die Bindestriche und das ".zip") durch doppelte Anführungszeichen (Gänsefüßchen) von den Datumsparametern trennen:

Quelltext
1:
2:
  s              := FormatDateTime('"NW-"mm"-"dd"-"yyyy".zip"',Date);
  Label6.Caption := s;

Das Ergebnis wäre z.B. der Dateiname "NW-03-29-2003.zip". In der Hilfe kannst du nachlesen, wie man mit dem Befehl umgeht.

Ein evtl. anderer potentieller Fehler betrifft den Namen des Zielordners ("target") in der INI-Datei. Ich kann ja nicht wissen wie er gespeichert wird, aber wenn z.B. der Backslash am Ende fehlt, würde beim Zusammensetzen von Zielordner und ZIP-Datei z.B. folgendes herauskommen "d:\TestOrdnerNW-03-29-2003.zip". Möglicherweise suchst du also die ZIP-Datei im Ordner vergeblich, dafür quillt dein Root-Ordner mit solchen Konstruktionen über.
Um dem vorzubeugen solltest du prüfen, ob die Variable "Target" mit einem Backslash endet, bzw. du solltest diesen ggf. anhängen:

Quelltext
1:
2:
  if(Target[length(Target)] <> '\') then
    Target       := Target + '\';

Dann setzt du die Variablen zusammen:

Quelltext
1:
2:
3:
  Target         := Target + s;
  Source         := Source + '\*.*';
  run            := 'wzzip.exe';

und rufst das Programm auf:

Quelltext
1:
2:
3:
  ShellExecute(0,'open',pchar(run),pchar(Target + #32 + Source),
    pchar(path),SW_SHOWNORMAL);
end;

Beachte bitte, dass ich als letzten Parameter SW_SHOWNORMAL angegeben habe. Das dürfte wahrscheinlich dein eigentliches Problem lösen. Die Null, die du verwendet hast, steht für SW_HIDE; d.h.: das aufgerufene Programm wird unsichtbar im Hintergrund gestartet und ist nur im Taskmanager zu sehen.

So, das war´s.
Macht 10 €. :)


alex_id - Mo 31.03.03 16:59

Ich komme mir jetzt ichtig dumm vor :oops: :oops:
denn es lag wirklich nur an dem SW_SHOWNORMAL !!!!

Danke !!!

Alex

PS: Nimmst du auch Dollar ? :D


rmasterb - Mi 02.04.03 15:55
Titel: shellexecute
hallöchen,
ich mag vielleicht ein bischen unwissend erscheinen aber ich schaffes einfach nicht den shellexecute-befehl zu verwenden. der schreibt immer er kenne den befehl nicht obwohl ich die in der hilfe angegebene : ExtActns als unit eingebunden habe

merci für die hilfe


LCS - Mi 02.04.03 16:55
Titel: Re: shellexecute
Hi
rmasterb hat folgendes geschrieben:
hallöchen,
ich mag vielleicht ein bischen unwissend erscheinen aber ich schaffes einfach nicht den shellexecute-befehl zu verwenden. der schreibt immer er kenne den befehl nicht obwohl ich die in der hilfe angegebene : ExtActns als unit eingebunden habe

Da hat dich die Online-Hilfe aber schön vera...t. Du musst ShellAPI einbinden.

Gruss Lothar