2009-01-14 6 views
1

J'utilise la méthode ShowWindow de User32 pour masquer une fenêtre (cmd.exe) de l'utilisateur (principalement pour les empêcher de le fermer). Lorsque l'utilisateur ouvre le formulaire, le processus est démarré et masqué, puis lorsque le formulaire se ferme, le processus est arrêté. Cependant, lorsque le formulaire est à nouveau ouvert, il ne cache pas la fenêtre (et parfois ne l'est pas la première fois) Quelqu'un peut-il m'aider avec cela?ShowWindow de User32 n'agit pas comme prévu

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

Répondre

4

Il serait beaucoup plus facile à ceci:

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

A travaillé parfaitement, merci! – Malfist

0

Avez-vous vérifié si p.MainWindowHandle est une poignée valide? Ce doit être non nul, à tout le moins. Essayez d'appeler le IsWindow pour confirmer.

MSDN suggests appelant WaitForInputIdle avant de vérifier MainWindowHandle; vous pourriez accéder à la propriété avant que le nouveau processus ait créé sa fenêtre. La propriété est cependant intrinsèquement précaire, car les processus n'ont pas vraiment la notion de fenêtre "principale". Toutes les fenêtres sont traitées de manière égale. Le framework .Net désigne simplement la première fenêtre comme la principale, mais le processus lui-même n'a pas besoin de considérer les choses de cette façon.

Aussi, avez-vous envisagé de simplement cacher le processus au départ, au lieu de le démarrer et de vous cacher après le fait? Définissez les propriétés StartInfo du processus as Scotty2012 demonstrates.

Questions connexes