【问题标题】:User32's ShowWindow doesn't act as expectedUser32 的 ShowWindow 未按预期运行
【发布时间】:2010-10-01 11:10:45
【问题描述】:

我正在使用 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;
        }
    }

【问题讨论】:

    标签: c# .net system.diagnostics user32


    【解决方案1】:

    您是否检查过p.MainWindowHandle 是否为有效句柄?至少它必须是非零的。尝试拨打IsWindow确认。

    MSDN suggests 在检查MainWindowHandle 之前调用WaitForInputIdle;您可能在新进程创建其窗口之前访问该属性。但是,无论如何,该属性本质上是不稳定的,因为进程实际上并没有“主”窗口的概念。所有的窗户都一视同仁。 .Net 框架只是将第一个窗口指定为主窗口,但过程本身不需要这样考虑。

    另外,您是否考虑过最初只是隐藏进程,而不是启动它然后在事后隐藏?设置进程的StartInfo 属性as Scotty2012 demonstrates。

    【讨论】:

      【解决方案2】:

      这样会容易得多:

      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);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-12
        • 1970-01-01
        • 2020-06-28
        • 2012-02-18
        • 2018-01-18
        • 2012-06-14
        • 2019-03-03
        • 2012-09-21
        相关资源
        最近更新 更多