Entwickler-Ecke

Dateizugriff - Shellexecute in Konsolenanwendung


bf109g.01 - Di 11.05.10 16:15
Titel: Shellexecute in Konsolenanwendung
Hallo, habe jetzt einen Weile vergeblich in DH und Forum gesucht:
Ich möchte in einer Konsolenanwendung eine Shellexecute verwenden, aber das geht nicht ganz recht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
program C;

{$APPTYPE CONSOLE}

uses
  SysUtils, shellapi;
var eingabe:integer;
begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
  DeleteFile(ExtractFilePath(ParamStr(0))+'file.txt');
  writeLN(- 'File.txt deleted successfully');
  ShellExecute(handle,'open', PChar(ExtractFilePath(ParamStr(0))+'setup.exe'),
   NilNil, SW_NORMAL);
  writeNL('- Setup starts');readLn(Eingabe);

end.

Ich weiß nicht, was ich mit dem HWND-Wert machen soll (da wo 'handle' steht) und SW_NORMAL ist auch rot... WIe muss ich das ändern?

LG


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Di 11.05.2010 um 20:27


jaenicke - Di 11.05.10 16:35

Wenn du kein Handle hast, dann gib einfach 0 an. ;-)

Für die Konstante musst du die Unit Windows einbinden. Das zeigt dir Delphi in einem normalen Projekt einfach an, wenn du mit der Maus drüber gehst. ;-)


ALF - Di 11.05.10 16:37

hi,
Ich verstehe nicht, warum man hier immer vergisst zu prüfen!

Delphi-Quelltext
1:
2:
 DeleteFile(ExtractFilePath(ParamStr(0))+'file.txt');
 writeLN(- 'File.txt deleted successfully');
und davon aussgeht, wird schon funcen!
auf Deine Frage zu antworten:
evtl schreib mal Application.Handle und für sw_normal fehlt Dir evtl die unit Windows.

edit: mhhh.. einfach zu langsam
oder wie @jaenicke sagt, gib einfach 0 an 8)
Gruss Alf


elundril - Di 11.05.10 18:30

0 wird doch automatisch von delphi auf NIL verbessert, oder? warum dann nicht gleich NIL hinschreiben?

lg elundril


jaenicke - Di 11.05.10 18:32

Weil dort kein Zeiger sondern ein Handle (auf das Fenster, von dem aus das Programm ausgeführt werden soll) hinkommt. Nil geht nur für Zeigertypen, passt dort also nicht hin. ;-)


bf109g.01 - Di 11.05.10 21:52

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:

Ich verstehe nicht, warum man hier immer vergisst zu prüfen!
geht das vllt so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
program C;

{$APPTYPE CONSOLE}

uses
  SysUtils, shellapi;
var eingabe:integer;
begin
  try
    DeleteFile(ExtractFilePath(ParamStr(0))+'file.txt');
    writeLN(- 'File.txt deleted successfully');
  finally
    ShellExecute(handle,'open', PChar(ExtractFilePath(ParamStr(0))+'setup.exe'),
    NilNil, SW_NORMAL);
    writeNL('- Setup starts');readLn(Eingabe);
  end;
end.

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
evtl schreib mal Application.Handle und für sw_normal fehlt Dir evtl die unit Windows.

Application.handle fnktioniert nicht. Application ist ein unbekannter Bezeichner.

Werd jetzt versuchen '0' einzusetzen. Danke euch! :)


ALF - Di 11.05.10 22:08

user profile iconbf109g.01 hat folgendes geschrieben Zum zitierten Posting springen:
geht das vllt so:

Nein! Es reicht

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if DeleteFile(ExtractFilePath(ParamStr(0))+'file.txt'then
   writeLN(- 'File.txt deleted successfully')
else
begin
   writeLN(- 'File.txt not deleted or found')
  //evtl hier noch ein exit rein um das Proc zu beenden!?
end;

Hattest Du schon in der uses, Windows, mit eingebunden als Du es ausprobiert hast!
Gruss Alf


jaenicke - Di 11.05.10 22:14

user profile iconbf109g.01 hat folgendes geschrieben Zum zitierten Posting springen:
Application.handle fnktioniert nicht. Application ist ein unbekannter Bezeichner.
Klar, du hast ja auch keine Formularanwendung. Deshalb reicht 0. Und du hast ja sicher in der Hilfe schon gesehen, was Application ist und dass es in der Unit Forms deklariert ist... (oder? :roll:)


ALF - Di 11.05.10 22:19

Oh, Sorry @jaenicke, da hab ich ihm was falsches gesagt :oops:
Mein Fehler @bf109g.01. Also ganz schnell vergessen mit "Application.Handle" :tongue:

Gruss Alf


jaenicke - Di 11.05.10 22:26

Vielleicht einmal zur Erklärung was dieser Parameter eigentlich macht:
Zum Beispiel wird beim Anfordern von Adminrechten unter Vista / 7 das UAC Popup mittig in dem dort angegebenen Fenster angezeigt (eben z.B. beim Startmenü, wenn man von dort aus ein Programm startet). Gibt man dort 0 an heißt das, dass kein Fenster verfügbar ist dafür, also wird der Desktop benutzt und es dort mittig angezeigt.

Genau das gleiche gilt für etwaige Fehlermeldungen, die beim Aufruf von ShellExecute ausgelöst werden könnten. Die werden entsprechend positioniert.

Dementsprechend kann man einfach 0 hinschreiben, wenn man eben kein Fenster hat, auf das ein Dialogfenster bezogen werden könnte.


ALF - Di 11.05.10 23:08

Nice @jaenicke. Warum sind solche einfachen aber doch kongreten Beschreibungen, nicht in den allg. Hilfen drin, selbst in manchen Tut's! Das würde vielen helfen, manches besser zu verstehen, einschliesslich meiner wenigkeit!
Gruss Alf


elundril - Di 11.05.10 23:16

Hier [http://www.delphi-forum.de/viewtopic.php?p=605352] im Thread hat Jaenicke schon gesagt das die Win-API-Dokumentation bei der Delphi-Hilfe dabei ist. Alternativ kann man sich die runterladen oder einfach auf msdn nachsehen und dort steht das dann drin.

Bei Tutorials würde es vl. etwas den rahmen sprengen jede API-funktion zu erläutern.

lg elundril


ALF - Di 11.05.10 23:53

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Hier [http://www.delphi-forum.de/viewtopic.php?p=605352] im Thread hat Jaenicke schon gesagt das die Win-API-Dokumentation bei der Delphi-Hilfe dabei ist.

Ich will ja nicht den Thread überladen, aber bei mir in der DH7entrprise für shellexecute, ich weiss, ist nicht das aktuellste.
Zitat:

hwnd
Specifies a parent window. This window receives any message boxes that an application produces. For example, an application may report an error by producing a message box.

und das in der msdn
HWND
A handle to the owner window used for displaying a UI or error messages. This value can be NULL if the operation is not associated with a window.

Bei den Tut's meine ich ja auch nur die, die dort erwähnt werden.
Im allgm immer hilfreich, aber wie gesagt nicht immer so verständlich wie @jaenicke es in diesem Beispiel gezeigt hat. Ihr müsst das immer von einem Anfänger sehen, so wie ich :?

Aber gut, das gehört eh nicht hier rein!
Gruss Alf


bf109g.01 - Fr 14.05.10 18:54

So, danke soweit dür eure hilfreichen Beiträge.
Inzwischen hat sich nun ein neues Problem ergeben.

Wenn ich bei uses Windows hinzufüge, gibt es keine Probleme mehr mit dem SW_NORMAL beim Shellexecute, das wird dann nämlich erkannt.
Dafür gibt es dann eine Fehlermeldung bei DeleteFile:
Zitat:
E2010 Inkompatible Typen: 'string' und 'PAnsiChar'

Wenn ich Windows aus der uses-Liste nehme, funktioniert das wieder, nur bei SW_NORMAL gibts dann wieder einen unbekannten Bezeichner.


ALF - Fr 14.05.10 19:12

Schreib mal

Delphi-Quelltext
1:
ShellExecute(0PChar('open'), PChar(ExtractFilePath(ParamStr(0))+'setup.exe'), NilNil, SW_NORMAL);                    
Gruss Alf


Narses - Fr 14.05.10 19:27

Moin!

user profile iconbf109g.01 hat folgendes geschrieben Zum zitierten Posting springen:
Dafür gibt es dann eine Fehlermeldung bei DeleteFile:
Zitat:
E2010 Inkompatible Typen: 'string' und 'PAnsiChar'

Wenn ich Windows aus der uses-Liste nehme, funktioniert das wieder,
Schreib einfach den Namen der Unit dazu, dann klappt das auch mit Windows in der uses-Klausel: :idea: ;)

Delphi-Quelltext
1:
SysUtils.DeleteFile('C:\file.dat');                    
cu
Narses


Yogu - Fr 14.05.10 20:20

Sonst kannst du dir mit einem kleinen Trick behelfen, der von Delphi standardmäßig angewendet wird: Existieren zwei Funktionen in zwei unterschiedlichen Units deklariert wurden, wird im Zweifelsfall die aus der zuletzt eingebundenen Unit genommen. Deshalb lautet die Standard-uses-Klausel: Windows, { ...} , SysUtils { ... } :idea:

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
Schreib mal


Delphi-Quelltext
1:
ShellExecute(0PChar('open'), PChar(ExtractFilePath(ParamStr(0))+'setup.exe'), NilNil, SW_NORMAL);                    

Das ist nicht notwendig; Stringliterale werden vom Delphi-Compiler automatsich in ein PChar umgewandelt, falls notwendig.

Grüße,
Yogu


bf109g.01 - Fr 14.05.10 20:45

Danke, danke, ich hab einfach Windows vor SysUtils gestellt und alles funktioniert.
Freue mich gerade dämlich, weil meine erste Konsolenanwendung funzt. :) :)
Ich hätte noch eine abschließende Frage:
Das Programm schließt sich am Ende immer von allein wieder.
Wie ist der Befehl, dass die Konsole erst auf Tastendruck (Enter oder beliebig) schließt?


jaenicke - Fr 14.05.10 20:46

ReadLn ;-)


Teekeks - Fr 14.05.10 20:54

sowas in etwa:

Delphi-Quelltext
1:
2:
3:
var b:string;
//zum schluss:
readln(b);

Evtl. kann man unter Delphi auch den String weglassen.