在Window应用程序中写入命令行让它发挥得很好很好。例如,我有这段代码:[STAThread]staticvoidMain(string[]args){foreach(stringsinargs){System.Windows.Forms.MessageBox.Show(s);Console.WriteLine("字符串:"+s);}MutexappSingleton=newSystem.Threading.Mutex(false,"WinSyncSingalInstanceMutx");如果(appSingleton.WaitOne(0,false)){尝试{Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);//启动记录器Logger.singleton.makeOpen(true);应用程序运行(新主窗体(假));}catch(Exception){}最后{appSingleton.Close();Logger.singleton.makeOpen(false);}}else{System.Windows.Forms.MessageBox.Show("抱歉,一次只能运行一个WinSync实例。");它应该使用Console.WriteLine写入控制台,但我什么也看不到,只显示MessageBox。我究竟做错了什么?尝试AttachConsole(-1)重定向Console.Out,对我有用:usingSystem;使用System.Collections.Generic;使用System.Windows.Forms;使用System.Runtime.InteropServices;namespacePEFixer{staticclassProgram{[DllImport("kernel32.dll")]privatestaticexternboolAttachConsole(intdwProcessId);//////应用程序的主要入口点。///[STAThread]staticintMain(string[]args){if(args.Length>0){AttachConsole(-1);返回Form1.doTransformCmdLine(args);}else{Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);应用程序运行(新Form1());}返回0;}}}Windows应用程序模型让它有点痛苦。您需要将应用程序类型更改为控制台(在属性中),它应该神奇地开始工作。您的表单无论如何都会出现,因为它是由自动生成的代码明确创建的。我的建议是创建一个Windows应用程序,然后通过P/Invoke获取控制台。IE:publicForm1(){[DllImport("kernel32.dll")]publicstaticexternboolAllocConsole();[DllImport("kernel32.dll")]publicstaticexternboolFreeConsole();publicForm1(){AllocConsole();Console.WriteLine("随便吧");玩了一下,看到来自AllocConsole和AttachConsole的警告,我认为最好的主意是有两个.NETexe文件,比如foo.exe和fooconsole。EXE文件。当您需要控制台输出时使用fooconsole.exe。除了main函数之外的所有代码都可以放在一个.NET项目中,它会生成一个DLL(类库)。这包括所有获奖表格,包括您的主窗口。exe项目中唯一剩下的就是一个小的主函数,它依次调用DLL中的静态函数。所有这些都可以在不借助P-Invoke的情况下完成。在您的DLL类库中:usingSystem;使用System.Windows.Forms;命名空间MyNamespace{publicclassMainEntry{privatestaticboolmIsConsole=false;privateMainEntry(){}publicstaticboolIsConsoleApp{get{returnmIsConsole;}}publicstaticintDoMain(string[]args,boolisConsole){mIsConsole=isConsole;try{//做任何事-主程序执行return0;//“Good”DOS返回代码}catch(Exceptionex){if(MainEntry.IsConsoleApp){Console.Error.WriteLine(ex.Message);}else{MessageBox.Show(ex.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);}返回1;//"Bad"DOSreturncodeindicatesfailure}}}}在发出WindowsEXE(foo.exe)的项目中,这是唯一的代码:usingSystem;namespaceMyNamespace{staticclassProgram{[STAThread]staticintMain(string[]args){returnMainEntry.DoMain(args,false);在发出控制台EXE(fooconsole.exe)的项目中,这是唯一的代码:usingSystem;namespaceMyNamespace{staticclassProgram{[STAThread]staticintMain(string[]args){returnMainEntry.DoMain(args,true);}}}当然在这两个EXE项目中你需要在项目属性的“应用程序”选项卡上引用同一个解决方案中的DLL项目,你可以更改项目类型——Windows应用程序(EXE),控制台应用程序(EXE)或类库(DLL)。请注意,可以通过编程方式确定EXE是使用Windows还是控制台子系统,但这可能不值得-很多P-Invoke并且您必须查看EXE的PE标头的字节。此外,AllocConsole/AttachConsole方法很有趣,如果您从命令行或批处理文件运行您的程序,并尝试将输出(stdout和/或stderr)重定向到一个文件,它不会工作-它不会'不要转到那个文件。请参阅http://www.nabble.com/WIN32:-Spawning-a-command-line-process-td21681465.html同样,它可以解决,但它需要更多的P-Invoke,可能不值得。作为最佳实践,我从来不会在EXE项目中放置一个简单的Main函数,它会依次调用DLL中的静态函数。原因有很多,但一个很好的理由是单元测试工具与DLL比EXE更有效。还要注意Main函数的形式,它采用字符串数组作为参数,并返回一个int。这是最常用的形式,因为您可以在批处理文件中使用ERRORLEVEL来处理您的EXE返回的任何数字——传统上0表示成功,大于0表示失败。您是从VisualStudio还是从命令行以调试模式(F5)运行它?在VS中,您将在“输出”选项卡中看到控制台输出(Ctrl+Alt+O)。否则,没有可写入的控制台。你需要它做什么?如果是为了调试(因为用户永远看不到控制台),那么我推荐使用Debug.WriteLine()。那么应该可以顺利进入控制台了。。。以上就是C#学习教程:在window应用程序中编写命令行的全部内容分享。注意——本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
