Announcement

Collapse
No announcement yet.

Problem mit ShellExecute und FindWindow

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem mit ShellExecute und FindWindow

    <HTML>
    <HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
    <META NAME="Generator" CONTENT="Microsoft Word 97">
    <TITLE>Hallo, ich möchte ein Berechnungsorogramm von mir aus einer BCB1</TITLE>
    <META NAME="Template" CONTENT="C:\Programme\Microsoft Office\Office\html.dot">
    </HEAD>
    <BODY LINK="#0000ff" VLINK="#800080">

    <P>Hallo, ich m&ouml;chte ein Berechnungsorogramm von mir aus einer BCB1.0 Application unter NT4.0 fernsteuern. Dazu benutze ich folgenden Code:</P>

    <B><P>void __fastcall</B> TForm1::ProgrammAufrufen</P><DIR>
    <DIR>

    <P>(<B>char</B> *ClassName, <B>char</B> *ExeName, <B>long</B> Command, <B>long</B> Param)</P></DIR>
    </DIR>

    <P>{</P><DIR>
    <DIR>

    <P>HWND hWnd;</P>
    <B><P>for</B>(<B>int</B> i=0; i&lt;2; i++)</P>
    <P>{ </P><DIR>
    <DIR>

    <P>hWnd=FindWindow(ClassName,NULL);</P>
    <B><P>if</B>(hWnd==NULL)</P>
    <P>{</P><DIR>
    <DIR>

    <P>ShellExecute(Form1-&gt;Handle,"open",ExeName,0,0,SW_SHOWNORMAL);</P></DIR>
    </DIR>

    <P>}</P>
    <B><P>else</B> <B>break</B>;</P></DIR>
    </DIR>

    <P>}</P>
    <B><P>if</B>(hWnd==NULL) <B>return</B>;</P>
    <P>PostMessage(hWnd,WM_COMMAND,Command,Param);</P></DIR>
    </DIR>

    <P>}</P>

    <P>Wenn das Fenster nicht gefunden wurde, mu&szlig; das Programm gestartet werden. Beim zweiten Durchlauf der Schleife sollte es dann gefunden werden. Wird es aber nicht. Statt dessen wird es zweimal gestartet. Wenn ich statt <B>ShellExecute</B> das gute alte <B>WinExec</B> nehme, funktioniert es. Wenn ich das Programm vorher schon aufgerufen habe, geht es auch. Was mache ich falsch ? </P>

    <P>Danke - G&uuml;nther</P></BODY>
    </HTML>
    Günther

  • #2
    Hallo Günther,

    ich denke es ist ein Zeitproblem. In der SDK ist unter Winexec zu lesen:
    In Win32, the WinExec function returns when the started process calls the GetMessage function or a time-out limit is reached. To avoid waiting for the time out delay, call the GetMessage function as soon as possible in any process started by a call to WinExec.
    D.h., WinExe returned erst wenn das Programm komplett gestartet ist.
    Mit dem ShellExec-Aufruf, wird der Prozess gestartet, wenn das Programm gefunden wurde und aufgerufen werden konnte. Da Deine Loop natürlich viel schneller ist als die Ausführung des anderen Programmes (Window-Handle anmelden usw.) bis zum Erscheinen au dem Schirm, hast Du diesen Effekt. Wenn Du nach ShellExecute eine Loop einbaust do
    (FindWindow(ClassName,NULL)

    Comment


    • #3
      Hallo Günther,

      ich denke es ist ein Zeitproblem. In der SDK ist unter Winexecute zu lesen:
      In Win32, the WinExec function returns when the started process calls the GetMessage function or a time-out limit is reached. To avoid waiting for the time out delay, call the GetMessage function as soon as possible in any process started by a call to WinExec.
      D.h., WinExe returned erst wenn das Programm komplett gestartet ist.
      Mit dem ShellExec-Aufruf, wird der Prozess gestartet, wenn das Programm gefunden wurde und aufgerufen werden konnte. Da Deine Loop natürlich viel schneller ist als die Ausführung des anderen Programmes (Window-Handle anmelden usw.) bis zum Erscheinen au dem Schirm, hast Du diesen Effekt. Wenn Du nach ShellExecute eine Loop einbaust z.B. do
      {
      hwnd = FindWindow(ClassName,NULL);
      } while (!hwnd);
      müsste es klappen.
      Das Du in Eine Dead-Loop läufst kann auch nicht passieren, wenn Du den Rückgabewert von ShellExecute auswertest:
      If the function fails, the return value is an error value that is less than or equal to 32.

      Mfg
      Gerhar

      Comment


      • #4
        Hallo Gerhard, erst mal Danke...

        Ich habe heute ein paar Einstellungen auf meinem Rechner geändert, und das führt dazu, daß das Berechnungsprogramm beim Aufruf über WinExec ein falsches Arbeitsverzeichnis bekommt und ein paar Dateien nicht mehr finden kann. Es wird dann mit einer Fehlermeldung beendet, ohne daß das Hauptfenster erzeugt wird. Ist ja auch alles in Ordnung. Meine BCB Application kann ich dann noch normal beenden, aber der C++ Builder spielt verrückt: Wenn ich ihn beenden will, erhalte ich die Frage "Der Debugger läuft gerade. Abbrechen ?". Wenn ich OK klicke, erhalte ich einen Debugger-Kernel-Fehler, Fehlercode 2. Den BC++ Builder kann ich nur noch über den Task-Manager beenden.

        Beim Aufruf über ShellExecute habe ich dieses Problem nicht, dann liegt das Berechnungsprogramm im richtigen Arbeitsverzeichnis, weil ich mit der BCB-Application vorher dahin gewechselt habe.

        Allerdings steckt irgendwo noch ein Fehler im Programm, den ich jetzt suchen muß. Es könnte daran liegen, daß es jetzt die 32 bit Version ist, und daß die übergebenen Parameter bei ShellExecute anders sind als bei WinExec. Kriegt er einmal _argv und einmal GetCommandLine ??? kann doch gar nicht sein ! Werde es untersuchen... Das mit der Zeitschleife hatte ich in ähnlicher Form schon mal probiert. Erst mal danke, ich mach jetzt Schluß... Günthe
        Günther

        Comment


        • #5
          Hi!!

          du möchtest also vorher überprüfen, ob ein bestimmtes Programm läuft. Du benutzt dazu FindWindow. Probiers doch mal aus, indem du einfach nach dem Titel (Form1->Caption suchst) suchst. Dann schreibst du einfach statt

          hWnd=FindWindow(ClassName,NULL);

          hWnd = FindWindow(NULL, "Name des Titels");

          So habe ich es bisher auch immer getan und hatte noch keine Probleme. Vielleicht hilft es dir ja weiter.

          Gruß Philip

          Comment


          • #6
            Hallo Phillip,

            FindWindow(ClassName,NULL); ist sicherer als FindWindow(NULL, "Name des Titels"); sofern man den ClassName eindeutig kennt, weil es ein eigenes Programm ist. Es kommt immer auf die Situation an. Hier liegt das Problem ein klein wenig woanders.

            Günthe
            Günther

            Comment


            • #7
              Also, erst mal zur Erläuterung: Mein Berechnungsprogramm muß den ersten Aufrufparameter auswerten, um den (Netzwerk)Pfad zu seinen Datendateien zu ermitteln. Dabei muß es feststellen, ob es bei meinen Kollegen oder einem Kunden, lokal oder im Netz, oder ob es bei mir auf dem Entwicklungsrechner läuft.

              Wird es "normal" gestartet, dann steht der Parameter in Anführungszeichen, wegen der Leerzeichen die in Pfaden möglich sind. Beim Start über WinExec fehlen die Zeichen. Ich krieg mein Programm aber jetzt nicht soweit, daß es mit WinExec korrekt läuft, irgendetwas stimmt da immer noch nicht.

              Mit ShellExecute funktioniert es jetzt, wenn ich hinter ShellExecute eine MessageBox setze und zeitverzögert auf OK klicke.

              Günthe
              Günther

              Comment

              Working...
              X