我有一个模块需要运行一个小的.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
的大多数不同工作组合,并且每个组合都会导致弹出恼人的黑匣子。该应用程序写入stdout但我只使用它进行调试,用户不应该真正看到它生成的文本。
据说CreateNoWindow
和/或RedirectStandardOutput
应该会阻止弹出框,但无论我如何设置这些变量都是如此。
答案 0 :(得分:5)
将命令行应用程序设置为Winforms应用程序,但不要像通常那样在执行时打开表单。
答案 1 :(得分: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
答案 2 :(得分:0)
这是一个在活动连接上询问MAC的示例代码,这是一个控制台应用程序,无需将其作为Windows窗体...
public class TestARP { private StringBuilder sbRedirectedOutput = new StringBuilder(); public string OutputData { get { return this.sbRedirectedOutput.ToString(); } } // Asynchronous! public void Run() { System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo(); ps.FileName = "arp"; ps.ErrorDialog = false; ps.Arguments = "-a"; ps.CreateNoWindow = true; // comment this out ps.UseShellExecute = false; // true ps.RedirectStandardOutput = true; // false ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // comment this out using (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(); // Comment this out } } void proc_Exited(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended"); } void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) { if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine); } }
现在,查看Run
方法,即处于异步模式,并作为单个控制台窗口运行 - 实际上是一个没有额外窗口弹出的普通控制台应用程序,请注意注释,如果你是更改这些行,它变成一个同步进程,很快就会发现,你会注意到这个控制台将创建另一个窗口,其中包含命令arp
的输出。因为它处于异步模式,所以输出被重定向到事件处理程序,该事件处理程序将数据填充到StringBuilder
实例中以供进一步处理...
希望这有帮助, 最好的祝福, 汤姆。