【问题标题】:Suppress command window from started command-line application with .NET使用 .NET 从已启动的命令行应用程序中抑制命令窗口
【发布时间】:2011-01-13 18:25:29
【问题描述】:

我有一个模块需要运行一个小的 .Net 命令行程序来检查更新。一切都很好,但是我无法阻止显示命令提示符输出。

该应用有自己的 Windows 窗体,如果检测到更新,它会弹出。更新需要作为单独的应用程序运行,因为它需要与启动它的 DLL 不同的执行上下文。

string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\" + AUTO_UPDATE_EXENAME;

updater.StartInfo.FileName = path;
updater.StartInfo.Arguments = AUTO_UPDATE_PARAMETERS;
updater.StartInfo.CreateNoWindow = false;
updater.StartInfo.UseShellExecute = false;
updater.StartInfo.RedirectStandardOutput = true;
updater.StartInfo.WorkingDirectory = path;

updater.Start();

我已经尝试了 CreateNoWindow、UseShellExecute 和 RedirectStandardOutput 的所有不同工作组合,它们中的每一个都会导致那个烦人的黑框弹出。该应用确实会写入标准输出,但我仅将其用于调试,用户不应真正看到它生成的文本。

据说CreateNoWindow 和/或RedirectStandardOutput 应该防止弹出框,但不管我如何设置这些变量。

【问题讨论】:

标签: c# .net process command-prompt


【解决方案1】:

这是一个在活动连接上询问 MAC 的示例代码,这是一个控制台应用程序,无需将其设为 Windows 窗体...

公共类TestARP { 私有 StringBuilder sbRedirectedOutput = new StringBuilder(); 公共字符串输出数据 { 得到 { 返回 this.sbRedirectedOutput.ToString(); } } // 异步! 公共无效运行() { System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo(); ps.FileName = "arp"; ps.ErrorDialog = 假; ps.Arguments = "-a"; ps.CreateNoWindow = true; // 注释掉这个 ps.UseShellExecute = 假; // 真的 ps.RedirectStandardOutput = true; // 错误的 ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // 注释掉这个 使用(System.Diagnostics.Process proc = new System.Diagnostics.Process()) { proc.StartInfo = ps; proc.Exited += new EventHandler(proc_Exited); proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived); proc.Start(); proc.WaitForExit(); proc.BeginOutputReadLine(); // 注释掉这个 } } void proc_Exited(对象发送者,EventArgs e) { System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended"); } void proc_OutputDataReceived(对象发送者,System.Diagnostics.DataReceivedEventArgs e) { if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine); } }

现在,看看Run 方法,它处于异步模式,并作为单个控制台窗口运行 - 实际上是一个普通的控制台应用程序,没有弹出额外的窗口,请注意 cmets,如果您要更改它们行,它变成了一个同步的进程,很快,你会注意到这个控制台将创建另一个带有命令arp的输出的窗口。因为它处于异步模式,所以输出被重定向到事件处理程序,该处理程序将数据填充到 StringBuilder 实例中以供进一步处理...

希望这会有所帮助, 最好的祝福, 汤姆。

【讨论】:

    【解决方案2】:

    您可以像这样在启动时隐藏窗口:

    using System.Runtime.InteropServices;
    
    namespace MyConsoleApp {    
        class Program    {        
    
            [DllImport("user32.dll")]        
            public static extern IntPtr FindWindow(string lpClassName,
                                                   string lpWindowName);   
    
            [DllImport("user32.dll")]       
            static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
            [STAThread()]
            static void Main(string[] args)        
            {          
                Console.Title = "MyConsoleApp";
    
                if (args.StartWith("-w"))            
                {                   
                    // hide the console window                    
                    setConsoleWindowVisibility(false, Console.Title);                   
                    // open your form                    
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);                    
                    Application.Run( new frmMain() );           
                }           
                // else don't do anything as the console window opens by default    
            }        
    
            public static void setConsoleWindowVisibility(bool visible, string title)       
            {             
                //Sometimes System.Windows.Forms.Application.ExecutablePath works  
                // for the caption depending on the system you are running under.           
                IntPtr hWnd = FindWindow(null, title); 
    
                if (hWnd != IntPtr.Zero)            
                {               
                    if (!visible)                   
                        //Hide the window                    
                        ShowWindow(hWnd, 0); // 0 = SW_HIDE                
                    else                   
                         //Show window again                    
                        ShowWindow(hWnd, 1); //1 = SW_SHOWNORMA           
                 }        
            }
        }
    }
    

    http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/ea8b0fd5-a660-46f9-9dcb-d525cc22dcbd

    【讨论】:

      【解决方案3】:

      将命令行应用程序设置为 Winforms 应用程序,但不要像往常一样在执行时打开表单。

      【讨论】:

      • 这不会阻止他写入标准输出吗?
      • stdout 不再需要,我也通过我们的标准日志接口记录它
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多