我已经阅读了一些关于组合Windows窗体和控制台应用程序的程序的主题,但似乎我的问题还没有解决 . 是否可以从cmd-line运行程序并能够通过表单和cmd-line命令控制应用程序?它的意思是:
为应用程序的普通用户通过(Windows窗体)表单控制应用程序,
用于调试和高级用户通过控制台控制应用程序(并可选择查看Windows窗体中发生的情况))
我知道我想要的东西是非常重要的,它可能意味着很多工作,但我仍然想知道如何正确地做到这一点 .
这并不难,只需P / Invoke AllocConsole()API函数来创建自己的控制台 . 例如,使您的Program.cs源代码文件如下所示:
static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); #if DEBUG CreateConsole(); #endif Application.Run(new Form1()); } static void CreateConsole() { var t = new System.Threading.Thread(() => { AllocConsole(); for (; ; ) { var cmd = Console.ReadLine(); if (cmd.ToLower() == "quit") break; // Etc... } FreeConsole(); }); t.IsBackground = true; t.Start(); } [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool AllocConsole(); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool FreeConsole(); }
您只需要使用ApplicationContext而不是表单本身启动Windows窗体应用程序 . 然后,您不依赖于要显示的主窗体,并且可以像控制台应用程序一样工作 .
您也可以自己创建一个命令行可执行文件并与Windows窗体库链接以使用它们 .
另一种方法是使用某种启动器,启动Windows窗体应用程序,以及通过本地网络或其他一些进程间通信,或类似系统与Windows窗体应用程序通信的命令行工具 - many ways lead to Rome . ..
是的,你想要的是非常可能的 . 你有选择 . 有些我能想到...:
使用UI自动化编写可以连接到Windows窗体应用程序并控制它的控制器应用程序 . 这是Windows Vista中的新增功能 . 在 System.Windows.Automation 命名空间中打包了托管类,这些托管类首先在WPF中发布,它已经到达.NET 3.0 . (现在我考虑一下,我不确定"new in Windows Vista"是否真的 . 它可能是"new in .NET 3.0",这意味着它也适用于Windows XP . 嗯......)UI自动化不需要对Windows窗体应用程序进行代码更改,但它可以是低级别的,因为你需要编写每个鼠标点击或剪切/粘贴 . 见the answer to Stack Overflow question Is there a way to control a third-party EXE file from VB.NET? .
System.Windows.Automation
修改Windows窗体应用程序以通过WM_COPYDATA接口公开其功能 . 然后您的客户端应用程序可以与它通信 . 同样,这里的模型是两个不同的应用程序,其中一个可以控制或询问另一个 . .NET Reflector tool就是这种方法的一个很好的例子 . 有一个ReflectorController,作为the ReflectorAddins project on CodePlex的一部分提供 . 控制器是一个命令行工具,可以向Reflector发送 WM_COPYDATA 消息,告诉它打开一个新程序集,导航到一个特定的类,依此类推 .
WM_COPYDATA
控制器的代码:http://reflectoraddins.codeplex.com/sourcecontrol/network/Show?projectName=reflectoraddins&changeSetId=29526#19979
此方法适用于任何Windows窗体应用程序 . 您需要覆盖WndProc方法 . 要查看方法,请查看The Code Project article Use WM_COPYDATA to send data to/from C++ and C# Windows processes .
我还使用这种方法构建了一个基于Windows窗体的进度监视器,可以直观地显示长时间运行的测试的进度 .
我相信还有其他选择 .
我记得在从Python的命令行界面(IDLE)控制Windows窗体的演示中使用了IronPython .
Edit: 我找不到原始视频,但是这个应该显示出可能没有太多努力的可能性 . See this video并跳到19:00 .
这是可能的 . 您将不得不考虑线程化Windows窗体表单,可能在同一进程中使用单独的application domain . 您可以考虑创建一个代理对象(一种继承MarshalByRefObject的消息类) .
通常,在查看应用程序时,您有一个UI层和一个业务层(以及一个数据层,谁知道更多层) . 您可以将控制台客户端视为UI层(使用简单的命令输入)和Windows窗体客户端作为另一个 .
只需在应用程序启动时检查命令行参数 . 如果指定了参数,则实例化简单控制台类,否则实例化(可能更复杂的)Windows窗体类 .
如果您希望更改反映在Windows窗体应用程序中(同时从控制台应用程序控制它),请尽可能使用数据绑定设置应用程序 . 让您的业务层反映应用程序中实际发生的情况 .
6 回答
这并不难,只需P / Invoke AllocConsole()API函数来创建自己的控制台 . 例如,使您的Program.cs源代码文件如下所示:
您只需要使用ApplicationContext而不是表单本身启动Windows窗体应用程序 . 然后,您不依赖于要显示的主窗体,并且可以像控制台应用程序一样工作 .
您也可以自己创建一个命令行可执行文件并与Windows窗体库链接以使用它们 .
另一种方法是使用某种启动器,启动Windows窗体应用程序,以及通过本地网络或其他一些进程间通信,或类似系统与Windows窗体应用程序通信的命令行工具 - many ways lead to Rome . ..
是的,你想要的是非常可能的 . 你有选择 . 有些我能想到...:
使用UI自动化编写可以连接到Windows窗体应用程序并控制它的控制器应用程序 . 这是Windows Vista中的新增功能 . 在
System.Windows.Automation
命名空间中打包了托管类,这些托管类首先在WPF中发布,它已经到达.NET 3.0 . (现在我考虑一下,我不确定"new in Windows Vista"是否真的 . 它可能是"new in .NET 3.0",这意味着它也适用于Windows XP . 嗯......)UI自动化不需要对Windows窗体应用程序进行代码更改,但它可以是低级别的,因为你需要编写每个鼠标点击或剪切/粘贴 . 见the answer to Stack Overflow question Is there a way to control a third-party EXE file from VB.NET? .修改Windows窗体应用程序以通过WM_COPYDATA接口公开其功能 . 然后您的客户端应用程序可以与它通信 . 同样,这里的模型是两个不同的应用程序,其中一个可以控制或询问另一个 . .NET Reflector tool就是这种方法的一个很好的例子 . 有一个ReflectorController,作为the ReflectorAddins project on CodePlex的一部分提供 . 控制器是一个命令行工具,可以向Reflector发送
WM_COPYDATA
消息,告诉它打开一个新程序集,导航到一个特定的类,依此类推 .控制器的代码:http://reflectoraddins.codeplex.com/sourcecontrol/network/Show?projectName=reflectoraddins&changeSetId=29526#19979
此方法适用于任何Windows窗体应用程序 . 您需要覆盖WndProc方法 . 要查看方法,请查看The Code Project article Use WM_COPYDATA to send data to/from C++ and C# Windows processes .
我还使用这种方法构建了一个基于Windows窗体的进度监视器,可以直观地显示长时间运行的测试的进度 .
我相信还有其他选择 .
我记得在从Python的命令行界面(IDLE)控制Windows窗体的演示中使用了IronPython .
Edit: 我找不到原始视频,但是这个应该显示出可能没有太多努力的可能性 . See this video并跳到19:00 .
这是可能的 . 您将不得不考虑线程化Windows窗体表单,可能在同一进程中使用单独的application domain . 您可以考虑创建一个代理对象(一种继承MarshalByRefObject的消息类) .
通常,在查看应用程序时,您有一个UI层和一个业务层(以及一个数据层,谁知道更多层) . 您可以将控制台客户端视为UI层(使用简单的命令输入)和Windows窗体客户端作为另一个 .
只需在应用程序启动时检查命令行参数 . 如果指定了参数,则实例化简单控制台类,否则实例化(可能更复杂的)Windows窗体类 .
如果您希望更改反映在Windows窗体应用程序中(同时从控制台应用程序控制它),请尽可能使用数据绑定设置应用程序 . 让您的业务层反映应用程序中实际发生的情况 .