Entwickler-Ecke

Windows API - problem mit ShellExecute


chrisx - So 23.01.05 12:21
Titel: problem mit ShellExecute
ich habe ein programm geschrieben, das, wenn die systemzeit, mit der, in einem editfeld übereinstimmt ein anderes programm ausführen soll!
ich habe einen timer verwendet, der jede halbe sekunde überprüft, ob der zeitpunkt da ist...


hier ein teil des programms:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormTimer(Sender: TObject);
begin
if TimeToStr(now) = Edit1.Text then ShellExecute(Application.Handle, 'open''C:\alarm.exe'nilnil, SW_SHOW);
end;


aber wenn ich das programm starten will, kommt folgende fehlermeldung:

Ausgabedatei C:\alarm.exe kann nicht erstellt werden.


Radioactive - So 23.01.05 12:28

Wenn du welches Programm starten willst?

Alarm.exe:
Probier mal den Aufruf von ShellExecute so:

Delphi-Quelltext
1:
ShellExecute(Application.Handle,'open','C:\',nil,'alarm.exe',SW_SHOW);                    

dann müsste es eigentlich klappen.

Timer-Programm:
vielleicht den Timer erst später starten, also, wenn das Programm schon ganz gestartet ist.


ScorpionKing - So 23.01.05 12:49

Radioactive hat folgendes geschrieben:
Wenn du welches Programm starten willst?

Alarm.exe:
Probier mal den Aufruf von ShellExecute so:

Delphi-Quelltext
1:
ShellExecute(Application.Handle,'open','C:\',nil,'alarm.exe',SW_SHOW);                    

dann müsste es eigentlich klappen.

Timer-Programm:
vielleicht den Timer erst später starten, also, wenn das Programm schon ganz gestartet ist.


das ist ja müll. sorry radioactive, aber das ist so. tut mir echt leid, aber dann übergibst du C:\ den Parameter 'alarm.exe' und da C:\ kein Programm ist, klappt das nicht.

Das Application.Handle muss glaub ich durch NULL ersetzt werden. nur ne vermutung!


chrisx - So 23.01.05 13:09

jetzt wird das programm zwar erzeugt, aber es wird nicht alarm.exe geöffnet, sondern, nur C:\ .

ich habe ds jetzt so eingebaut:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormTimer(Sender: TObject);
begin
if TimeToStr(now) = Edit1.Text then ShellExecute(Application.Handle,'open','C:\',nil,'alarm.exe',SW_SHOW);
end;


ScorpionKing - So 23.01.05 13:26

so müsste es klappen:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormTimer(Sender: TObject);
begin
if TimeToStr(now) = Edit1.Text then ShellExecute(NULL, 'open''C:\alarm.exe'nilnil, SW_SHOW);
end;


ich habe doch gesagt, das wenn man das so macht, nicht geht, da dann nur C:\ aufgerufen wird:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormTimer(Sender: TObject);
begin
if TimeToStr(now) = Edit1.Text then ShellExecute(NULL, 'open''C:\'nil'alarm.exe', SW_SHOW);
end;


so klappt es nicht! habe ich doch geschrieben! :roll: :roll: :roll:

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.


chrisx - So 23.01.05 14:50

hmm....
ich habe das jetzt so gemacht, wie du es beschrieben hast, aber dann wir das programm zwar kimpiliert, aber wenn der zeitpunkt zum öffnen erreicht ist, kommt folgende fehlermeldung:

Variante des Types (Null) konnte nicht in Typ (Int64) konvertiert werden.


raziel - So 23.01.05 14:53

Dann schreib mal besser

Delphi-Quelltext
1:
2:
ShellExecute(0'open''C:\alarm.exe'nilnil, SW_SHOW);
end;

;)

raziel


chrisx - So 23.01.05 14:56

danke!

Jetzt funktioniert es!


bis11 - So 23.01.05 14:58

Probiere es mal sorum :


Delphi-Quelltext
1:
shellexecute(handle,PChar('Open'),PChar('C:\alarm.exe'),nilnil, sw_normal);                    


Dein Fehler ist es, Du übergibts es als String und shellexecute erlaubt nur Char. Sollte das ganze immer noch nicht funktionieren, dann starte das Programm so :


Delphi-Quelltext
1:
winexec('C:\alarm.exe');                    


Karlson - So 23.01.05 15:05

bis11 hat folgendes geschrieben:
Probiere es mal sorum :


Delphi-Quelltext
1:
shellexecute(handle,PChar('Open'),PChar('C:\alarm.exe'),nilnil, sw_normal);                    


Dein Fehler ist es, Du übergibts es als String und shellexecute erlaubt nur Char. Sollte das ganze immer noch nicht funktionieren, dann starte das Programm so :


Delphi-Quelltext
1:
winexec('C:\alarm.exe');                    


Wenn das das Problem gewesen wäre, hätte er schon zu beginn einen Kompliererror gebracht.
Das Problem bestand wohl eher darin, dass das Programm beim ShellExecute aufruf beendet wurde, ergo war das Application.Handle ungültig.


bis11 - So 23.01.05 15:10

Karlson hat folgendes geschrieben:
Wenn das das Problem gewesen wäre, hätte er schon zu beginn einen Kompliererror gebracht.
Das Problem bestand wohl eher darin, dass das Programm beim ShellExecute aufruf beendet wurde, ergo war das Application.Handle ungültig.


Ich habe das bis jetzt immer so gemacht und es hat hervorragend funktioniert. Ich wusste nicht, das man das auch als String übergeben kann :) Danke aber für die Info, habe wieder was dazu gelernt. :D


Karlson - So 23.01.05 15:21

bis11 hat folgendes geschrieben:
Karlson hat folgendes geschrieben:
Wenn das das Problem gewesen wäre, hätte er schon zu beginn einen Kompliererror gebracht.
Das Problem bestand wohl eher darin, dass das Programm beim ShellExecute aufruf beendet wurde, ergo war das Application.Handle ungültig.


Ich habe das bis jetzt immer so gemacht und es hat hervorragend funktioniert. Ich wusste nicht, das man das auch als String übergeben kann :) Danke aber für die Info, habe wieder was dazu gelernt. :D


PCHar ist im Grunde nichts anderes als ein String. Sozusagen ein Pointer auf eine Charkette. PChar gibt es um Kompatibilitätsprobleme mit Windows, bzw. anderen Programmiersprachen (bei der DLL Programmierung) zu verhindern. In Visual Basic ist z.B. jeder String ein PCHar. Lange Rede kurzer sinn:

Wenn du einen konstanten Pfadnamen angibst, brauchst du keinen Cast in PCHar vorzunehmen, weil du als konstante auch keinen String sondern eben diesen Pointer angibst, der Compiler sieht 'c:\alarm.exe' schließlich nicht als String an.
Den TypeCast brauchst du nur, wenn du eine Variable übergibst.


NeoInDerMATRIX - So 23.01.05 16:27

Hi,

du solltest sicher gehen das die Datei existiert befor du ShellExecute benutt. Oder benutze eine Function von Luckie die nicht schlecht ist.


Delphi-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:
Function RunProcess(AFileName: String; AShowCmd: DWORD; AWait: Boolean; AProcID: PDWORD): LongWord;
Var
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
Begin
    FillChar(StartupInfo, SizeOf(StartupInfo), #0);
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW Or STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := AShowCmd;
    If Not CreateProcess(Nil, PChar(AFileName), NilNil, False, DETACHED_PROCESS Or NORMAL_PRIORITY_CLASS, NilNil, StartupInfo, ProcessInfo) Then
        Result := WAIT_FAILED
    Else
    Begin
        If AWait = False Then
        Begin
            If Assigned(AProcID) Then
                AProcID^ := ProcessInfo.dwProcessId;
            Result := WAIT_FAILED;
        end
        else
        Begin
            If Assigned(AProcID) Then
                AProcID^ := INVALID_HANDLE_VALUE;
            WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
            GetExitCodeProcess(ProcessInfo.hProcess, Result);
        End;
    End;
    If ProcessInfo.hThread <> 0 Then
        CloseHandle(ProcessInfo.hThread);
    If ProcessInfo.hProcess <> 0 Then
        CloseHandle(ProcessInfo.hProcess);
End;


Vorher mit

Delphi-Quelltext
1:
 If FileExists(...) Then                    

prüfen ob die datei existiert. Dann sollte es gehen!

Cu
Neo


Karlson - So 23.01.05 20:41

Das Problem ist schon längst gelöst und hatte eigentlich auch nichts damit zu tun, das die Destdatei nicht existierte ;)