Laden...

process.WaitForExit(); wartet unter XP, aber nicht unter Win7 64bit

Erstellt von cosmicgirl72 vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.915 Views
C
cosmicgirl72 Themenstarter:in
33 Beiträge seit 2008
vor 14 Jahren
process.WaitForExit(); wartet unter XP, aber nicht unter Win7 64bit

Hallo,

ich habe ein Problem mit dem process.WaitForExit() bei Windows 7 64-bit.Folgender Code läuft einwandfrei mit XP,Vista und Windows 7 32-bit.Es soll die DxDiag aufgerufen und gespeichert werden.Bis die DxDiag gespeichert ist, soll der weitere Programmablauf gestoppt werden d.h.die Form erst dann geladen werden.

 private void Form1_Load(object sender, EventArgs e)
        {
            System.Diagnostics.Process process3 = new System.Diagnostics.Process();
            process3.StartInfo.FileName = "C:\\Windows\\System32\\dxdiag.exe";
            process3.StartInfo.Arguments = " /whql:off /t  c:\\Windows\\Temp\\DxDiag.txt";
            process3.Start();
           
            process3.WaitForExit();
            if (process3.HasExited)
            {
                MessageBox.Show("Prozess beendet");//zur Kontrolle
            }

und so weiter............

Leider wird die Anweisung process3.WaitForExit() bei 64-bit ignoriert, und die MessageBox kommt,obwohl die Datei noch nicht gespeichert ist.Was mache ich da falsch, oder wie kann man das eleganter lösen, daß das Programm nicht weiterläuft, bis die DxDiag gespeichert wurde?

Danke

Katrin

1.361 Beiträge seit 2007
vor 14 Jahren

Hi cosmicgirl,

  1. Zieh dir mal den ProcessExplorer von http://live.sysinternals.com/. Und schau dir das Startverhalten von DxDiag an.
    (Achte insbesondere auf das Starten mehrerer gleicher/unterschiedlicher Instanzen von DxDiag. Die ProcExp.exe zeigt das schön farbig an. Grün für neue Prozesse und Rot für gestorbene, das "glüht" dann auch immernoch etwas nach)

Das Problem unter x64 wird sein, dass das DxDiag-Programm ein 32-bittiges ist. Und entweder muss es mit WOW64 irgendwie im 32-Bit Modus emuliert werden, und/oder es detektiert selber, dass es auf ner 64-Bit maschine läuft und startet sich selbst neu in der passenden 64-Bit Edition.

In jedem Fall (und das hast du ja auch selber detektiert) beendet sich der initiale Prozess (nachdem er selbst die irgendwie anders geartete Version gestartet hat).

Ist denn dein Programm selbst als 64-Bit kompiliert?
Wenn beide Programme 64Bit sind, dann läuft es auch auf ner 64-Bit Maschine korrekt laufen. Denn in der WinAPI ist kein Fehler.
Aber wenn DxDiag irgendwie sich selbst neu startet (oder der WOW64-Mechanismus das tut, ist ja auch egal) ... mhh... was machst du dann??? ... gute Frage. 👅
Hab grad leider keine Antwort parat. Aber wenigstens ist dir das Problem jetzt erstmal klarer. (Ist doch immerhin schon etwas 😉 )

beste Grüße
zommi

C
cosmicgirl72 Themenstarter:in
33 Beiträge seit 2008
vor 14 Jahren

Danke für Deine schnelle Antwort.Wie kann man das Programm als 64-bit kompilieren?Ich programmiere nicht so viel.
Mein Programm läuft ja mit 64 bit, außer daß halt nicht gewartet wird, bis der Prozess beendet wurde.Das Programm läuft einfach weiter und dann kommt im weiteren Ablauf eine Fehlermeldung,daß die Datei DxDiag.txt nicht vorhanden ist.

1.361 Beiträge seit 2007
vor 14 Jahren

Hi cosmicgirl,

bei 64Bit sind ja Datentypen ganz andere als bei 32Bit. Pointer beispielsweise.
Und ein Programm kommuniziert ja während seiner Lebenszeit mit dem Betriebssystem (Dateien lesen/schreiben, Bildschirmausgaben, Oberflächen, ...)

Somit sind generell 64 und 32 Bit imkompatibel. Allerdings bietet Windows den sogenannten WindowsOnWindows64 (WOW64)-Modus an, wo ein 32-Bit Windows für dich simuliert wird, alles is wie bei 32Bit und die Programme laufen auch noch unter x64.

Ich selbst hab zwar noch nicht mit 64Bit gearbeitet, aber du kannst wohl im VisualStudio die Zielplattform auf 64Bit einstellen. Dann kann dein Programm zumindest direkt auf x64 laufen. (Wobei doch eigentlich managed C#-Code Platform-invariant ist 🤔 )

Soweit das Vorwort. Wie DxDiag nun aussieht, weiß ich nicht, das sollst du ja mit dem ProcessExplorer herausfinden.
Aber eventuell (wäre ne Vermutung) tut es sowas in der Art:


main(...)
{
 if(IsWow64Process(...))
 {
    CreateProcess("DxDiag64Bit.exe");
    return;
 }
 else
 {
  ...
 }
}

oder auch was ganz anderes.

Aber vielleicht kannst du auch einfach warten, bis die Datei fertig geschrieben wurde ? Mit dem FileSystemWatcher vielleicht?

beste Grüße
zommi

C
cosmicgirl72 Themenstarter:in
33 Beiträge seit 2008
vor 14 Jahren

Wo kann man das denn einstellen?Ich benutze die Express-Version von 2008.
Ach so, es wird stadnardmäßig die 32-bit Version von DxDiag aufgerufen.Man kann aber die 64-bit- Version aud em geöffneten DxDiag Programm ausführen.

1.361 Beiträge seit 2007
vor 14 Jahren

Hi cosmisgirl72,

was passiert denn wenn du dxdiag noch zusätzlich mit nem "/64bit"-Flag aufrufst aus deinem C# programm? (evtl. n anderer Flag, genaueres könnte dir "dxdiag /?" oder so mitteilen)

beste Grüße
zommi

1.361 Beiträge seit 2007
vor 14 Jahren

Hi cosmicgirl,

ich habe das nun selbst mal ausprobiert.
Und siehe da: Das dxdiag startet sich (auch unter windows 64bit) standardmäßig immer als 32-Bit Version.
(Erkennt man im Taskmanager am kleinen Zusatz bei dem "dxdiag.exe *32" )

Somit beendet sich dxdiag wirklich sogleich und startet sich als 32-Bit Variante neu - genau weshalb du auch ein Process.Exit wahrnimmst.

Und ja, das "/64bit"-Flag hilft.
Dann bleibt dxdiag einfach im 64-Bit Modus. (Kein Process Restart und damit kein verfrühtes Exit)

Da aber das dxdiag auf nem 32-Bit-System den "/64bit"-Schalter nicht kennt, musst du wohl in deinem c# programm unterscheiden, ob du mit 64 oder 32 Bit läufst.
Aber das sollte mit IntPtr.Size möglich sein.

beste Grüße
zommi

V
78 Beiträge seit 2008
vor 14 Jahren

Da aber das dxdiag auf nem 32-Bit-System den "/64bit"-Schalter nicht kennt, musst du wohl in deinem c# programm unterscheiden, ob du mit 64 oder 32 Bit läufst.
Aber das sollte mit IntPtr.Size möglich sein.

Noch ne kleine Anmerkung wie das geht:
Wenn IntPtr.Size == 4 ist es ein 32-Bit OS ( 4 Byte = 32 Bit )
Und falls IntPtr.Size == 8 ist es ein 64 Bit OS ( 8 Byte = 64 Bit )

Also einfach abfragen, ob IntPtr.Size == 8 und dann mit dem /64bit Parameter starten.

C
cosmicgirl72 Themenstarter:in
33 Beiträge seit 2008
vor 14 Jahren

Danke für Deine Hilfe!Werde es versuchen.

Liebe Grüße

Katrin

C
cosmicgirl72 Themenstarter:in
33 Beiträge seit 2008
vor 14 Jahren

Da aber das dxdiag auf nem 32-Bit-System den "/64bit"-Schalter nicht kennt, musst du wohl in deinem c# programm unterscheiden, ob du mit 64 oder 32 Bit läufst.
Aber das sollte mit IntPtr.Size möglich sein.

Hallo Zommi,

habe es an der Arbeit so probiert.Es funktioniert jetzt auch bei 64-bit!Vielen Dank!

Ich wünsche Dir ein schönes Wochenende!

Liebe Grüße

Katrin