Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Problem mit aus Delphi-Programm gestarteter Java Anwendung (https://www.delphipraxis.net/151019-problem-mit-aus-delphi-programm-gestarteter-java-anwendung.html)

R2009 3. Mai 2010 11:28


Problem mit aus Delphi-Programm gestarteter Java Anwendung
 
Hi DP'ler,
ich bin schier am verzweifeln.
Wir (müssen) ein Java Kommandozeilentool verwenden um unsere Zählermodems zu konfigurieren.
Da dieses Tool sehr rudimentär aufgebaut ist haben wir uns entschlossen, mit Delphi, eine Oberfläche
drumrum zu bauen.
Das Kommandozeilentool nimmt Verbindung über Modem, seriell und IP auf.
Das Kommandozeilentool funktioniert immer.

Alles funktioniert, ausser Modem, wenn ich mein Tool nutze und das Modem in einem nicht IBM PC steckt oder angeschlossen ist.
Aufgerufen wird das Ganze über diese Funktion (hab ich mir hier irgendwo gezogen).
Die Pipes werden genutzt um irgendwelche Informationen zu bekommen wenn der Java Prozess beendet ist.
An den Java Quellcode komme ich nicht heran.

Delphi-Quellcode:
function GetConsoleOutput(const Command: String; var Output, Errors: TStringlist): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  SecurityAttr: TSecurityAttributes;
  PipeOutputRead: THandle;
  PipeOutputWrite: THandle;
  PipeErrorsRead: THandle;
  PipeErrorsWrite: THandle;
  Succeed: Boolean;
  Buffer: array [0..255] of Char;
  NumberOfBytesRead: DWORD;
  Stream: TMemoryStream;
begin
  //Initialisierung ProcessInfo
  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);

  //Initialisierung SecurityAttr
  FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
  SecurityAttr.nLength := SizeOf(SecurityAttr);
  SecurityAttr.bInheritHandle := true;
  SecurityAttr.lpSecurityDescriptor := nil;

  //Pipes erzeugen
  CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
  CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);

  //Initialisierung StartupInfo
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb:=SizeOf(StartupInfo);
  StartupInfo.hStdInput := 0;
  StartupInfo.hStdOutput := PipeOutputWrite;
  StartupInfo.hStdError := PipeErrorsWrite;
  StartupInfo.wShowWindow := sw_Hide;
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

  if CreateProcess(nil, PChar(command), nil, nil, true,
  CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil,
  StartupInfo, ProcessInfo) then
  begin
    result:=true;
    //Write-Pipes schließen
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsWrite);

    //Ausgabe Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
      while true do
      begin
        application.ProcessMessages;
        succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
        if not succeed then break;
        Stream.Write(Buffer, NumberOfBytesRead);
      end;
      Stream.Position := 0;
      Output.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;
    CloseHandle(PipeOutputRead);

    //Fehler Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
      while true do
      begin
        application.ProcessMessages;
        succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil);
        if not succeed then break;
        Stream.Write(Buffer, NumberOfBytesRead);
      end;
      Stream.Position := 0;
      Errors.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;
    CloseHandle(PipeErrorsRead);

    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    CloseHandle(ProcessInfo.hProcess);
  end
  else begin
    result:=false;
    CloseHandle(PipeOutputRead);
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsRead);
    CloseHandle(PipeErrorsWrite);
  end;
end;
Kann irgendjemand mal über diesen Codeschnipsel schauen ob dort etwas offentsichtlich faul ist.

Grüsse
Rainer

Bernhard Geyer 3. Mai 2010 13:14

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Felche Fehlernummer liefert CreateProcess/GetLastError?

Was passiert auf diesen PC wenn du die Java-Anwendung direkt startest ohne deine Anwendung?

Astat 3. Mai 2010 13:20

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Zitat:

Zitat von R2009
..ich bin schier am verzweifeln.

Ja, kann das nachvollziehen, hört sich ja alles trivial an, ist es aber nicht!


Lade Dir das Teil unter #5 runter, berücksichtigt alles was mir derzeit so untergekommen ist.

http://www.delphipraxis.net/internal...801&highlight=

Thread #5

lg. Astat

R2009 3. Mai 2010 13:53

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Hi Bernhard,

Zitat:

Felche Fehlernummer liefert CreateProcess/GetLastError?

Was passiert auf diesen PC wenn du die Java-Anwendung direkt startest ohne deine Anwendung?
Das mit der Fehlernummer habe ich noch nicht ausprobiert.
Ohne meine Oberfläche läuft das Tool einwandfrei.

Grüsse
Rainer

TurboMartin 3. Mai 2010 14:10

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Wie startest Du den dieses Komandozeilenprogramm. Ansonsten könntest Du dir auch mal jdGui anschauen ;)

R2009 4. Mai 2010 06:50

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Hallo Bernhard,
du hattest nach der Fehlernummer gefragt:
Einen Fehler gibt es nicht, die Shell wird aufgerufen, nur passiert nichts was das Modem betrifft.
Offentsichtlich scheint es "nur" ein Problem mit der Art des Aufrufs des Java Tools zu geben.

Nochmal zur Vorgehensweise (Reihenfolge der Aufrufe):
1.) Mein Tool ruft über cmd.exe eine Batchdatei auf.
2.) In der Batchdatei steht:
@echo off
java.exe -jar -Dlog4j.configuration=file:log4j.xml D:\source_elster\uploadtool\uploadtool.jar %*

es müsste doch auch möglich sein java unter umgehung der cmd.exe direkt aufzurufen oder?
Ich stell mir vor, dass ich dann ein Problem weniger habe?

Grüsse
Rainer

himitsu 4. Mai 2010 07:29

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Wieso ruft dein Tool die java.exe nicht selber auf, sondern geht erst über die Batch-Datei?

R2009 4. Mai 2010 10:02

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Hi himitsu,

Diese Batch Datei, mitsamt dem Java commandtool, wurde uns vom Hersteller so übergeben.
Um kompatibel zu bleiben habe ich das halt so realisiert.

An alle die mir geholfen haben:
ich habe den Fehler gefunden, jedoch wäre es mir noch lieber wenn
ich auch die Ursache kennen würde.
Mir ist aufgefallen, dass es im createprocess einen parameter gibt, der den aktuellen Pfad enthält.
In meinem Aufruf stand da nur nil drin.
Ersetzt man den mit Pfeilen gekennzeichneten Parameter durch nil, funktioniert das ganze auf IBM Laptops auf
HP Laptops nicht.
Ich gehe davon aus, dass die cmd shell sich nach dem Aufruf in irgendeinen subshare befindet, aber nicht in meinem Programmverzeichnis.

Delphi-Quellcode:
  if CreateProcess(nil, PChar(command), nil, nil, true,
  CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or REALTIME_PRIORITY_CLASS, nil, --->pchar(directory)<-----,
  StartupInfo, ProcessInfo) then
  begin
    ...
Dies ist mein Aufruf:
Delphi-Quellcode:
  dstr:='/c uploadtool.bat -i '+par[2]+' -f '+par[1]+' -t '+par[3]+' -p '+edit1.text+' -d';
  GetConsoleOutput('cmd '+dstr,actpath,c,d);
Zitat:

The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.

BOOL CreateProcess(

LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);
Wenn jetzt noch jemand die Ursache (bzw die Umgebungsvariable) kennt die das verursacht wäre ich richtig glücklich.

Grüsse
Rainer

Astat 4. Mai 2010 15:30

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Zitat:

Zitat von R2009
Wenn jetzt noch jemand die Ursache (bzw die Umgebungsvariable) kennt die das verursacht wäre ich richtig glücklich.

Also die Sourcen hast Du dir nicht angesehen, oder? :gruebel:

Da Guckst Du --> uPipedProcess.pas

ist alles drinn was Du brauchst.

lg. Asat

R2009 5. Mai 2010 05:07

Re: Problem mit aus Delphi-Programm gestarteter Java Anwendu
 
Hi Astat,

F e h l e r g e f u n d e n!

Mir fehlt nur noch die Erklärung warum cmd bzw java (Rechnerabhängig) das Einstiegsverzeichnis ändert.

Mit Verlaub gesagt waren mir deine Sourcen etwas zu aufwändig und komplex.

Grüsse
Rainer


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz