Question

J'utilise la méthode ShowWindow de User32 pour masquer une fenêtre (cmd.exe) de l'utilisateur (principalement pour l'empêcher de la fermer). Lorsque l'utilisateur ouvre le formulaire, le processus est lancé et masqué, puis, lorsque le formulaire est fermé, le processus est tué. Cependant, lorsque le formulaire est ouvert à nouveau, il ne cache pas la fenêtre (et parfois pas la première fois) Quelqu'un peut-il m'aider avec cela?

    [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;
        }
    }
Était-ce utile?

La solution

Cela serait BEAUCOUP plus facile:

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

Autres conseils

Avez-vous vérifié si p.MainWindowHandle est un descripteur valide? Ce doit être au moins non nul. Essayez d'appeler IsWindow pour confirmer.

MSDN suggère d'appeler WaitForInputIdle avant de vérifier MainWindowHandle ; vous pouvez accéder à la propriété avant que le nouveau processus ait créé sa fenêtre. Toutefois, la propriété est intrinsèquement précaire, car les processus n’ont pas vraiment la notion de "principal". la fenêtre. Toutes les fenêtres sont traitées de manière égale. Le framework .Net désigne simplement la première fenêtre comme étant la fenêtre principale, mais le processus lui-même n’a pas à prendre en compte les choses de cette façon.

De plus, avez-vous envisagé de masquer simplement le processus au lieu de le démarrer puis de le cacher après coup? Définissez le StartInfo du processus du processus. propriétés comme le montre Scotty2012 .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top