User32 des Showwindow wirkt nicht wie erwartet
-
22-07-2019 - |
Frage
ich die Showwindow-Methode von User32 bin mit einem Fenster (cmd.exe) von dem Benutzer zu verbergen (vor allem zu verhindern, dass es zu schließen). Wenn der Benutzer das Formular öffnet, wird der Prozess gestartet, und versteckte sich, dann, wenn die Form der Prozess abgebrochen wird schließt. Wenn jedoch die Form wieder geöffnet wird, ist es nicht das Fenster schließen (und manchmal nicht das erste Mal) Kann jemand mir dabei helfen?
[DllImport("User32")]
private static extern int ShowWindow(int hwnd, int nCmdShow); //this will allow me to hide a window
public ConsoleForm(Process p) {
this.p = p;
p.Start();
ShowWindow((int)p.MainWindowHandle, 0); //0 means to hide the window. See User32.ShowWindow documentation SW_HIDE
this.inStream = p.StandardInput;
this.outStream = p.StandardOutput;
this.errorStream = p.StandardError;
InitializeComponent();
wr = new watcherReader(watchProc);
wr.BeginInvoke(this.outStream, this.txtOut, null, null);
wr.BeginInvoke(this.errorStream, this.txtOut2, null, null);
}
private delegate void watcherReader(StreamReader sr, RichTextBox rtb);
private void watchProc(StreamReader sr, RichTextBox rtb) {
string line = sr.ReadLine();
while (line != null && !stop && !p.WaitForExit(0)) {
//Console.WriteLine(line);
line = stripColors(line);
rtb.Text += line + "\n";
line = sr.ReadLine();
}
}
public void start(string[] folders, string serverPath) {
this.inStream.WriteLine("chdir C:\\cygwin\\bin");
//this.inStream.WriteLine("bash --login -i");
this.inStream.WriteLine("");
}
private void ConsoleForm_FormClosed(object sender, FormClosedEventArgs e) {
this.stop = true;
try {
this.p.Kill();
this.p.CloseMainWindow();
} catch (InvalidOperationException) {
return;
}
}
Lösung
Es wäre viel einfacher, diese:
public ConsoleForm(Process p) {
this.p = p;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
p.Start();
this.inStream = p.StandardInput;
this.outStream = p.StandardOutput;
this.errorStream = p.StandardError;
InitializeComponent();
wr = new watcherReader(watchProc);
wr.BeginInvoke(this.outStream, this.txtOut, null, null);
wr.BeginInvoke(this.errorStream, this.txtOut2, null, null);
}
Andere Tipps
Haben Sie überprüft, ob p.MainWindowHandle
ein gültiges Handle ist? Es muss nicht Null sein, zumindest. Versuchen Sie fordern IsWindow
zu bestätigen.
MSDN schlägt Aufruf WaitForInputIdle
vor MainWindowHandle
Überprüfung; Sie können die Eigenschaft zugreifen, bevor der neue Prozess sein Fenster geschaffen hat. Das Anwesen ist von Natur aus unsicher wie auch immer, aber, weil Prozessen wirklich keine Vorstellung von den „main“ Fenstern. Alle Fenster werden gleich behandelt. Der .NET-Framework einfach bezeichnet das erste Fenster als Haupt ein, aber der Prozess selbst muss nicht Dinge auf diese Weise betrachten.
Außerdem haben Sie darüber nachgedacht, einfach den Prozess versteckt zunächst, anstatt es zu starten und dann nach der Tat versteckt? Legen Sie die StartInfo
Eigenschaften als Scotty2012 demonstriert.