4

我有一个模块需要运行一个小的 .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();

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

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

4

3 回答 3

5

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

于 2010-02-06T01:05:42.677 回答
3

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

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

于 2010-02-06T01:12:06.030 回答
0

这是一个在活动连接上询问 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方法,即在异步模式下,并作为单个控制台窗口运行 - 实际上是一个普通的控制台应用程序,没有弹出额外的窗口,注意注释,如果你要更改这些行,它就会变成同步的处理脱壳,很快,您会注意到此控制台将创建另一个窗口,其中包含命令的输出arp。因为它处于异步模式,所以输出被重定向到事件处理程序,该事件处理程序将数据填充到StringBuilder实例中以供进一步处理......

希望这会有所帮助,最好的问候,汤姆。

于 2010-02-06T01:38:59.430 回答