Domanda

Sto usando il metodo ShowWindow da User32 per nascondere una finestra (cmd.exe) all'utente (principalmente per impedire che venga chiusa). Quando l'utente apre il modulo, il processo viene avviato e nascosto, quindi alla chiusura del modulo il processo viene interrotto. Tuttavia, quando il modulo viene aperto di nuovo, non nasconde la finestra (e talvolta non la prima volta) Qualcuno può aiutarmi con questo?

    [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;
        }
    }
È stato utile?

Soluzione

Sarebbe MOLTO più semplice:

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

Altri suggerimenti

Hai verificato se p.MainWindowHandle è un handle valido? Deve essere diverso da zero, almeno. Prova a chiamare IsWindow per confermare.

MSDN suggerisce chiamando WaitForInputIdle prima di controllare MainWindowHandle ; potresti accedere alla proprietà prima che il nuovo processo abbia creato la sua finestra. La proprietà è comunque intrinsecamente precaria, poiché i processi in realtà non hanno una nozione di "main" finestra. Tutte le finestre sono trattate allo stesso modo. Il framework .Net designa semplicemente la prima finestra come quella principale, ma il processo stesso non deve considerare le cose in questo modo.

Inoltre, hai considerato semplicemente di nascondere inizialmente il processo, anziché avviarlo e poi nasconderlo dopo il fatto? Imposta il StartInfo del processo / a> properties come dimostra Scotty2012 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top