ShowWindow User32 не работает, как ожидалось
-
22-07-2019 - |
Вопрос
Я использую метод ShowWindow из User32, чтобы скрыть окно (cmd.exe) от пользователя (главным образом, чтобы они не закрывали его). Когда пользователь открывает форму, процесс запускается и скрывается, затем, когда форма закрывается, процесс уничтожается. Однако, когда форма открывается снова, она не скрывает окно (а иногда и не в первый раз). Может ли кто-нибудь помочь мне с этим?
[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;
}
}
Решение
Это было бы НАМНОГО проще:
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);
}
Другие советы
Вы проверили, является ли p.MainWindowHandle
допустимым дескриптором? Это должно быть ненулевым, по крайней мере. Попробуйте позвонить в IsWindow
для подтверждения. р>
MSDN предлагает вызвать WaitForInputIdle
перед проверкой <код> MainWindowHandle код>; возможно, вы обращаетесь к свойству до того, как новый процесс создаст свое окно. Тем не менее, это свойство ненадежно по своей природе, потому что процессы на самом деле не имеют понятия «основной». окно. Все окна обрабатываются одинаково. Инфраструктура .Net просто определяет первое окно как главное, но сам процесс не должен так думать.
Кроме того, рассматривали ли вы просто сначала скрыть процесс вместо его запуска, а затем скрыть факт? Установите для процесса StartInfo
свойства , как демонстрирует Scotty2012 . Р>