Pregunta

Estoy usando el método ShowWindow de User32 para ocultar una ventana (cmd.exe) del usuario (principalmente para evitar que la cierren). Cuando el usuario abre el formulario, el proceso se inicia y se oculta, luego, cuando el formulario se está cerrando, el proceso finaliza. Sin embargo, cuando el formulario se abre nuevamente, no oculta la ventana (y a veces no lo hace la primera vez) ¿Alguien puede ayudarme con esto?

    [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;
        }
    }
¿Fue útil?

Solución

Sería MUCHO más fácil para esto:

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

Otros consejos

¿Ha verificado si p.MainWindowHandle es un identificador válido? Debe ser distinto de cero, como mínimo. Intente llamar a IsWindow para confirmar.

MSDN sugiere llamar a href = "http://msdn.microsoft.com/en-us/library/system.diagnostics.process.waitforinputidle.aspx" rel = "nofollow noreferrer"> WaitForInputIdle antes de verificar MainWindowHandle ; es posible que esté accediendo a la propiedad antes de que el nuevo proceso haya creado su ventana. Sin embargo, la propiedad es inherentemente precaria porque los procesos realmente no tienen una noción de `` principal '' ventana. Todas las ventanas son tratadas por igual. El marco .Net simplemente designa la primera ventana como la principal, pero el proceso en sí no necesita considerar las cosas de esa manera.

Además, ¿ha considerado simplemente ocultar el proceso inicialmente, en lugar de iniciarlo y luego esconderse después del hecho? Establezca el StartInfo del proceso propiedades como demuestra Scotty2012 .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top