Вопрос

Я использую метод 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 .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top