Pergunta

Eu estou usando o método ShowWindow de User32 para ocultar uma janela (cmd.exe) do usuário (principalmente para os impedir de fechá-lo). Quando o usuário abre o formulário, o processo é iniciado, e se escondeu, em seguida, quando o formulário está fechando o processo é morto. No entanto, quando o formulário é aberto novamente, ele não esconde a janela (e, por vezes, não pela primeira vez) alguém pode me ajudar com isso?

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

Solução

Seria muito mais fácil para isso:

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

Outras dicas

Você verificou se p.MainWindowHandle é um identificador válido? Ele deve ser diferente de zero, no mínimo. Tente chamar IsWindow para confirmar.

MSDN sugere chamada WaitForInputIdle antes de verificar MainWindowHandle; você pode estar acessando a propriedade antes do novo processo criou sua janela. A propriedade é inerentemente qualquer maneira precária, porém, porque os processos não têm realmente uma noção do "main" janela. Todas as janelas são tratados igualmente. O framework .Net designa simplesmente a primeira janela como a principal, mas o próprio processo não precisa considerar as coisas dessa forma.

Além disso, você já pensou em simplesmente escondendo o processo inicialmente, em vez de iniciá-lo e, em seguida, se escondendo após o fato? Definir StartInfo propriedades do processo como Scotty2012 demonstra .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top