User32 的 ShowWindow 未按预期运行
我使用 User32 中的 ShowWindow 方法向用户隐藏窗口 (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;
}
}
I am using the ShowWindow method from User32 to hide a window (cmd.exe) from the user (mainly to prevent them from closing it). When the user opens the form, the process is started, and hid, then when the form is closing the process is killed. However, when the form is opened again, it doesn't hide the window (and sometimes doesn't the first time) Can someone help me with this?
[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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这样做会容易得多:
It would be MUCH easier to this:
您是否检查过
p.MainWindowHandle
是否是有效的句柄? 至少它必须是非零的。 尝试致电IsWindow
进行确认。MSDN 建议 调用
WaitForInputIdle
在检查之前主窗口句柄
; 您可能会在新进程创建其窗口之前访问该属性。 不过,无论如何,该属性本质上是不稳定的,因为进程实际上并不具有“主”窗口的概念。 所有窗口都受到平等对待。 .Net 框架只是将第一个窗口指定为主窗口,但进程本身不需要以这种方式考虑事情。另外,您是否考虑过一开始就简单地隐藏该进程,而不是启动它然后在事后隐藏? 设置进程的
StartInfo
< /a> 属性如 Scotty2012 所示。Have you checked whether
p.MainWindowHandle
is a valid handle? It must be non-zero, at the very least. Try callingIsWindow
to confirm.MSDN suggests calling
WaitForInputIdle
before checkingMainWindowHandle
; you might be accessing the property before the new process has created its window. The property is inherently precarious anyway, though, because processes don't really have a notion of the "main" window. All windows are treated equally. The .Net framework simply designates the first window as the main one, but the process itself doesn't need to consider things that way.Also, have you considered simply hiding the process initially, instead of starting it and then hiding after the fact? Set the process's
StartInfo
properties as Scotty2012 demonstrates.