繁体   English   中英

C#中控制台的Windows Forms +命令

[英]Windows Forms + commands from the console in C#

我已经阅读了一些关于组合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窗体应用程序,以及通过本地网络或其他一些进程间通信, D-Bus或类似系统与Windows窗体应用程序通信的命令行工具 - 很多方式导致罗马 ......

是的,你想要的是非常可能的。 你有选择。 有些我能想到...:

  1. 使用UI自动化编写可以连接到Windows窗体应用程序并控制它的控制器应用程序。 这是Windows Vista中的新增功能。 System.Windows.Automation命名空间中打包了托管类,它首先在WPF中提供 ,它到达.NET 3.0。 (现在我考虑一下,我不确定“Windows Vista中的新功能”是否属实。它可能是“.NET 3.0中的新功能”,这意味着它也适用于Windows XP。嗯......)UI自动化需要没有代码更改到Windows窗体应用程序,但它可能是低级别的,因为您需要编写每个鼠标单击或剪切/粘贴。 请参阅Stack Overflow问题的答案有没有办法从VB.NET控制第三方EXE文件?

  2. 修改Windows窗体应用程序以通过WM_COPYDATA接口公开其功能。 然后您的客户端应用程序可以与它通信。 同样,这里的模型是两个不同的应用程序,其中一个可以控制或询问另一个。 .NET Reflector工具就是这种方法的一个很好的例子。 有一个ReflectorController,作为CodePlex上ReflectorAddins项目的一部分提供。 控制器是一个命令行工具,可以将WM_COPYDATA消息发送到Reflector,告诉它打开一个新程序集,导航到一个特定的类,等等。

    控制器的代码: http//reflectoraddins.codeplex.com/sourcecontrol/network/Show?projectName=reflectoraddins&changeSetId=29526#19979

    此方法适用于任何Windows窗体应用程序。 您需要覆盖WndProc方法。 要查看方法,请查看代码项目文章使用WM_COPYDATA向/从C ++和C#Windows进程发送数据

    我还使用这种方法构建了一个基于Windows窗体的进度监视器,可以直观地显示长时间运行的测试的进度。

  3. 在您的应用程序中,公开可以编程的COM服务器对象。 这正是Microsoft向应用程序公开Office功能的方式。 Office Automation允许任何支持COM的程序(C#, VBScriptPowerShell ,Perl,PHP等)“驱动”Office应用程序。 发生这种情况时,Office应用程序可见。 此方法还需要Windows窗体应用程序中的其他代码; 特别是你必须托管一个COM对象并将其连接到你的UI层。 如果您希望超级用户具有最大的灵活性,这可能是更可取的 - 他们可以编写自己的脚本来驱动该组件。

我相信还有其他选择。

我记得在Python的命令行界面( IDLE )中使用IronPython来控制Windows Forms的演示。

编辑:我找不到原始视频,但这个应该显示可能没有太多努力。 观看此视频并跳至19:00。

这是可能的。 您将不得不考虑线程化Windows窗体表单,可能在同一进程中使用单独的应用程序域 您可以考虑创建一个代理对象(一种继承MarshalByRefObject的消息类)。

通常,在查看应用程序时,您有一个UI层和一个业务层(以及一个数据层,谁知道更多层)。 您可以将控制台客户端视为UI层(使用简单的命令输入),将Windows窗体客户端视为另一个。

只需在应用程序启动时检查命令行参数。 如果指定了参数,则实例化简单控制台类,否则实例化(可能更复杂的)Windows窗体类。

如果您希望更改反映在Windows窗体应用程序中(同时从控制台应用程序控制它),请尽可能使用数据绑定设置应用程序。 让您的业务层反映应用程序中实际发生的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM