Entwickler-Ecke

Windows API - Parameter an EXE zur Laufzeit übergeben


Moonbiker - Di 07.03.06 02:03
Titel: Parameter an EXE zur Laufzeit übergeben
Hallo ihr,
habe ein Programm, welches ich zum Ports ansteuern nehme. Nun möchte ich, dass ich verschiedene sachen per Kommandozeile übergeben kann, allerdings ohne dazu etliche ProgrammInstanzen zu starten.
Dazu habe ich über mutex erreicht, dass ein weiterer Öffnungsversuch zwar geblockt wird, aber ich weis noch nicht, wie ich dennoch die Parameter auslesen kann, die übergeben wurden.

So lese ich innerhalb der Hauptroutine die Übergaben aus:

Delphi-Quelltext
1:
if ParamStr(1)='/remctrl' then if (ParamStr(2)<>''then MainForm.webcamctrl(ParamStr(2));                    


wobei in MainForm und zugehöriger Procedure alles verarbeitet werden soll.
An welche Stelle des Hauptprogramms muss ich nun eine Übergabe starten, oder welche Lösungsvorschläge könnt ihr mir machen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
program PortIO;

uses
  mutex in 'mutex.pas',
  Forms,
  main in 'main.pas' {MainForm};
{$R *.res}
begin
Application.Initialize;
Application.Title := 'PortSoftware';
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.


Ich habe auch schon überlegt, einfach eine neue Instanz zu starten und jene gleich wieder zu beenden, aber das hatte nicht funktioniert. (k.A. warum)

Vielen Dank, Michael


Delete - Di 07.03.06 02:11

Paramter werden beim Start ausgelesen. Wärend eine Instanz läuft ist es nicht möglich Parameter zu übergeben. Nicht umsonst heißen sie Startparameter. ;) Handelt es sich bei beiden Programmen, ujm Programmen vo dir, kannst du eine Interprozess Kommunkiation entweder über WM_COPYDATA, Memory Mapped Files oder Pipes realisieren.


Tino - Di 07.03.06 03:49

Schau mal hier:

...die Startparameter einer anderen Instanz übergeben? [http://www.delphi-library.de/topic_die+Startparameter+einer+anderen+Instanz+uebergeben_20679.html]
...verhindern dass die Anwendung mehrmals gestartet wird? [http://www.delphi-library.de/topic_verhindern+dass+die+Anwendung+mehrmals+gestartet+wird_19370.html]

Gruß
Tino


Moonbiker - Di 07.03.06 10:48

Ja es sind Programme von mir. Ich möchte aus einem php-script heraus meine Portsoftware ansprechen, um dann meine Webcam zu drehen. Anfangs hatte ich in der Portsoftware einen Timer, der dann eine Textdatei (die von php geschrieben wurde) ausgelesen hatte, und jene verändert hat, wenn es ein neuer Befehl war. Nur finde ich die Variante recht buggy und auch gefährlich.

Da ich in php nur "startparameter" übergeben kann, muss ich also ein zweites programm schreiben, was das erste bendient, richtgig? ich werde mir dazu die links mal anschauen. Da ich allerdings mit sowas noch nicht gearbeitet habe, werde ich sicher nochmal fragen ;)

Vielen Dank euch,
Michael

P.s.: es funktionierte im Übrigen weitere Startparameter an eine laufende Instanz zu übergeben, da ich sie in der mutex abgefangen hatte. Nur gab es da verschiedene Probleme, wie ihr euch sicher vorstellen könnt...



--> Vielen Dank, habe das Instanzen Tutorial gut verwenden können!


Moonbiker - Di 07.03.06 15:36

Habe das jetzt heilwegs gelöst:

Habe zum starten und stoppen ein anderes (Kommandozeilen-)Programm geschrieben:

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:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
program EchoT;
{$APPTYPE CONSOLE}

uses
  SysUtils, Forms, Windows, Tlhelp32, ShellApi;

procedure Wait(time: double);
  var Start: Integer;
  begin
    Start:=GetTickCount;
    while GetTickCount-Start <= time do application.ProcessMessages;
  end;

function KillTask(ExeFileName: string): integer;
  const
    PROCESS_TERMINATE=$0001;
  var
    ContinueLoop: BOOL;
    FSnapshotHandle: THandle;
    FProcessEntry32: TProcessEntry32;
  begin
    result := 0;

    FSnapshotHandle := CreateToolhelp32Snapshot
                      (TH32CS_SNAPPROCESS, 0);
    FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
    ContinueLoop := Process32First(FSnapshotHandle,
                                 FProcessEntry32); 

    while integer(ContinueLoop) <> 0 do
    begin
      
      if ((UpperCase(ExtractFileName(
                       FProcessEntry32.szExeFile)) =
          UpperCase(ExeFileName)) or
        (UpperCase(FProcessEntry32.szExeFile) =
          UpperCase(ExeFileName))) then

        Result := Integer(TerminateProcess(OpenProcess(
                        PROCESS_TERMINATE, BOOL(0),
                        FProcessEntry32.th32ProcessID), 0));

      ContinueLoop := Process32Next(FSnapshotHandle,
                                  FProcessEntry32);
    end;

    CloseHandle(FSnapshotHandle);
  end;
//Programmstart
begin
if ParamStr(1)='/remctrl' then if ParamStr(2)='/ctrl-disconnect' then
  begin
  KillTask('PortIO.exe');
  WriteLN('habe beendet: PortIO.exe');
  end;
if ParamStr(1)='/remctrl' then if ParamStr(2)='/ctrl-connect' then
  begin
  ShellExecute(0,Nil, PChar('D:\Public\HTTP\webcam\PortIO\PortIO.exe'), NilNil, SW_NORMAL);
  WriteLN('habe gestartet: PortIO.exe');
  end;
if ParamStr(1)='' then
  begin
  WriteLN('keine Aufgabe uebergeben');
  wait(10000);
  end;
end.

Das funktioniert soweit auch.

Auch kann ich an ein laufendes Programm übergebene Daten lesen, wenn es per Doppelklick oder Kommandozeile gestartet wurde.
Das Problem ist noch, dass wenn ich mit dem Hilfsprogramm starte, keine Oberfläche vorhanden ist, und das auch keine Befehle abgearbeitet werden.

Liegt das an Shellexecute?
Habt ihr wieder so ne gute Idee?

--> Habe mittlerweile auch rausbekommen, dass die Anwendung zwar gestartet wird, aber weder ins Form.Creat noch Form.Close geht, also muss irgendwo ja ein Absturzfehler sein, richtig?
Habe gerade was von createprocess gelesen, hilft mir das denn?


Moonbiker - So 12.03.06 20:21

Warum antwortet mir hier keine mehr?

Falsche Rubrik?