Wie zu warten, bis ein shell-Prozess beendet ist, bevor die Ausführung weiterer code in VB6
Ich habe ein kleines VB6-Anwendung, in der ich die Shell
Befehl, um ein Programm auszuführen. Ich bin speichern die Ausgabe des Programms in eine Datei. Ich bin dann diese Datei Lesen und setzen die Ausgabe auf dem Bildschirm mit einer Meldung in VB6.
Dies ist, was mein code jetzt so aussieht:
sCommand = "\evaluate.exe<test.txt "
Shell ("cmd.exe /c" & App.Path & sCommand)
MsgBox Text2String(App.Path & "\experiments\" & genname & "\freq")
Das problem ist, dass die Ausgabe, die das VB-Programm drucken mit der Meldung ist der alte Stand der Datei. Gibt es eine Möglichkeit, halten Sie die Ausführung von VB-code bis zu meinem shell-Befehl ein Programm beendet, so daß ich den korrekten Status der output-Datei und nicht in einem früheren Zustand?
- Dies ist, wie es zu tun: appspro.com/Tips/VBA%20Tips.htm Beispiel mit appspro.com/Downloads/ShellAndWait.zip
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die geheime Zutat dafür ist die
WaitForSingleObject
- Funktion, die blockiert die Ausführung Ihrer Anwendung Prozess, bis der angegebene Prozess abgeschlossen ist (oder Timeout). Es ist Teil des Windows-API, leicht aus einer VB 6 Anwendung nach dem hinzufügen der entsprechenden Erklärung zu deinem code.Diese Erklärung würde in etwa so Aussehen:
Es nimmt zwei Parameter: ein handle auf den Prozess, den Sie möchten, zu warten, und die time-out-Intervall (in Millisekunden), die gibt die maximale Menge an Zeit, die Sie warten wollen. Wenn Sie nicht angeben, eine time-out-Intervall (ein Wert von null), ist die Funktion nicht warten und sofort zurückgegeben. Wenn Sie angeben, dass ein unendliches Timeout-Intervall, die Funktion gibt nur, wenn der Prozess signalisiert, dass Sie abgeschlossen hat.
Bewaffnet mit diesem wissen, die einzige Aufgabe, die bleibt, ist, herauszufinden, wie man ein handle auf den Prozess, der Sie gestartet sind. Das erweist sich als ziemlich einfach, und kann erreicht werden, eine Reihe von verschiedenen Möglichkeiten:
Eine Möglichkeit (und die Art und Weise, ich würde es tun), ist die Verwendung des
ShellExecuteEx
- Funktion, auch aus der Windows-API, als ein drop-in Ersatz für dieShell
Funktion, die integriert ist in VB 6. Diese version ist weitaus vielseitiger und leistungsstärker, doch ebenso leicht mit der entsprechenden Erklärung.Es gibt einen handle auf den Prozess, der es erstellt. Alles, was Sie tun müssen, ist, übergeben Sie das handle an den
WaitForSingleObject
Funktion alshHandle
parameter, und du bist im Geschäft. Ausführung der Anwendung wird blockiert (angehalten), bis der Prozess, den Sie genannt haben beendet.Andere Möglichkeit ist die Verwendung der
CreateProcess
- Funktion (mal wieder, aus der Windows-API). Diese Funktion erzeugt einen neuen Prozess und seinen primären thread in dem gleichen Sicherheitskontext wie der aufrufende Prozess (D. H., VB-6-Anwendung).Microsoft veröffentlicht einen knowledge base-Artikel mit Details zu dieser Ansatz, der auch bietet eine vollständige Beispiel-Implementierung. Sie finden diesen Artikel hier: Wie Sie eine 32-Bit-Anwendung zu Bestimmen, Wann eine shellprozesses Endet.
Schließlich, vielleicht der einfachste Ansatz noch zu nutzen, ist die Tatsache, dass der eingebaute
Shell
Funktion Rückgabewert ist eine Anwendung, die task-ID. Dies ist eine eindeutige Nummer, identifiziert das Programm, das Sie angefangen hat, und es übergeben werden kann, um dieOpenProcess
- Funktion, um einen Prozess handle, der übergeben werden kann, um dieWaitForSingleObject
Funktion.Jedoch die Einfachheit dieses Ansatzes hat zu einem Preis kommen. Ein sehr wichtiger Nachteil ist, dass es bewirkt, dass Ihre VB 6 Anwendung vollständig nicht mehr reagiert. Denn es wird nicht die Verarbeitung von Windows-Botschaften, es wird nicht auf Benutzerinteraktionen reagieren oder sogar den Bildschirm neu zeichnen.
Die guten Leute über bei VBnet gemacht haben, vollständige Beispiel-code, der im folgenden Artikel: WaitForSingleObject: Bestimmen, wenn eine Ausgeführte App Beendet wurde.
ich würde gerne in der Lage sein zu reproduzieren, den code hier zu helfen Daube Weg von link rot (VB 6 ist immer dort oben in Jahren; es gibt keine Garantie, dass diese Ressourcen für immer um sein wird), aber die Verteilung der Lizenz in den code selbst angezeigt, um explizit zu verbieten.
Shell
Befehl". Ich erkläre, wie zum aufrufen von Funktionen aus der Windows-API zu tun, statt. War ich nicht deutlich? Edit: Yeah, never mind. Du hast Recht. Randy ' s code nicht verwendenShell
. Der erste Teil der Antwort war, was ich hatte, bevor Sie Googeln für bessere alternativen: ich würde Sie anrufenShellExecuteEx
ohne zu denken, viel weiter... ich werde das beheben.Shell
gewickeltShellExecute
, aber ich bin ehrlich gesagt nicht sicher. Sehr viel ich jedoch widersprechen, dass mitShellExecuteEx
stattdessen würden unerwünschte Folgen haben. Dies ist die gleiche Funktion, die aufgerufen wird, wenn Sie die "Ausführen" - dialog im Start-Menü. Ja, wenn Sie Sie bitten, es zu öffnen, eine Datei/Ordner-Pfad, es ist Thema zu öffnen in die aktuelle Explorer-Fenster. Das erwartete Verhalten für jemanden, der hat, die checkbox angekreuzt ist. Um dies zu erhalten, obwohl, müssen SielpOperation
entweder "öffnen" oder "Explorer" und geben Sie einen Pfad zu einem Ordner. Ist es nicht eigentlich "Fragen Sie ein Explorer-Fenster zu"ShellExecuteEx
ist der kanonische Weg der Laichzeit einen externen Prozess aus einem C-oder C++ - appGibt es keine Notwendigkeit zu greifen, um den zusätzlichen Aufwand der Aufruf von CreateProcess(), etc. Diese mehr oder weniger Duplikate der alte Randy Birch code aber es waren keine seinem Beispiel. Es gibt nur so viele Möglichkeiten, um der Haut eine Katze.
Hier haben wir eine vorgefertigte Funktion für handy-Nutzung, die gibt auch der exit-code. Legen Sie es in eine statische (.BAS) Modul-oder inline-Elemente in einem Formular oder einer Klasse.
Ich weiß, es ist ein Alter thread, aber...
Wie über die Verwendung der Windows Script Host Ausführen-Methode? Es hat eine bWaitOnReturn parameter.
Objekt.Run (strCommand, [intWindowStyle], [bWaitOnReturn])
intWindowStyle = 0, also cmd ausgeblendet werden
Tun Sie dies :
Referenz : http://support.microsoft.com/kb/129796
System.Diagnostics.Process.Start
, richtig?Environment.GetFolderPath
in VB 6. DieSystem.Environment
- Klasse ist Teil des .NET BCL. Es gibt keineProcess
Klasse, keineMessageBox.Show
usw. etc. Selbst die MSDN-Artikel, den du verlinkt sagt VB.NET.Große code. Nur ein winzig kleines problem: Sie müssen erklären, in der ExecCmd (nach Dim start As STARTUPINFO):
Dim ret as Long
Erhalten Sie eine Fehlermeldung, wenn Sie versuchen zu kompilieren, in VB6, wenn Sie nicht.
Aber es funktioniert Super 🙂
Freundlichen GRÜßEN
In meinen Händen, die csaba Lösung hängt mit intWindowStyle = 0, und nie übergibt die Kontrolle zurück zu VB. Der einzige Ausweg ist, um "Prozess beenden" im taskmanager.
Einstellung intWindowStyle = 3 und schließen Sie das Fenster manuell übergibt die Steuerung wieder
Habe ich gefunden, besser & einfachere Lösung:
und dann ist Sie einfach weiter mit Ihrem code.
Hoffe es hilft 😉