代码之家  ›  专栏  ›  技术社区  ›  MartyIX

Windows窗体+来自C中控制台的命令#

  •  8
  • MartyIX  · 技术社区  · 15 年前

    我读过一些关于结合Windows窗体和控制台应用程序的程序的主题,但我的问题似乎还没有解决。是否可以从命令行运行程序,并能够通过窗体和命令行命令控制应用程序?意思是:

    • 对于通过(Windows窗体)窗体控制应用程序的普通用户,
    • 用于调试和高级用户通过控制台控制应用程序(并可以选择查看Windows窗体中发生的情况)

    我知道我想要的是一件很重要的事情,这可能意味着很多工作,但我仍然想知道如何正确地完成它。

    6 回复  |  直到 13 年前
        1
  •  5
  •   Hans Passant    15 年前

    这并不难,只需p/invoke alloconsole()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();
      }
    
        2
  •  1
  •   Peter Mortensen icecrime    13 年前

    您只需要启动Windows窗体应用程序 ApplicationContext 而不是窗体本身。然后,您将不依赖于要显示的主窗体,并且可以像控制台应用程序一样工作。

    您还可以创建一个命令行可执行文件,并自己链接到Windows窗体库来使用它们。

    另一种方法是使用某种启动程序,启动Windows窗体应用程序,以及通过本地网络或其他进程间通信与Windows窗体应用程序通信的命令行工具, D-Bus 或类似的系统- many ways lead to Rome

        3
  •  1
  •   Community CDub    8 年前

    是的,你想要的是很可能的。你有选择。我能想到一些……:

    1. 使用UI自动化编写一个控制器应用程序,该应用程序可以连接到Windows窗体应用程序并对其进行控制。这是Windows Vista中的新功能。在 System.Windows.Automation 命名空间,它首先在 WPF ,它到达.NET 3.0。(现在我想起来了,我不确定“WindowsVista中的新功能”是真的。它可能是“新的.NET 3.0”,这意味着它也适用于WindowsXP。hmmm…)UI自动化不需要对Windows窗体应用程序进行代码更改,但它可能是低级的,因为您需要对每个鼠标单击或剪切/粘贴进行编程。见 the answer to Stack Overflow question Is there a way to control a third-party EXE file from VB.NET? .

    2. 修改Windows窗体应用程序以通过 WM_COPYDATA 接口。然后,您的客户机应用程序可以与它通信。这里的模型是两个不同的应用程序,其中一个可以控制或询问另一个。这个 .NET Reflector tool 这是一个很好的例子。有一个反射控制器,作为 the ReflectorAddins project on CodePlex . 控制器是一个命令行工具,可以发送 WM_COPYDATA 向Reflector发送消息,告诉它打开一个新的程序集,导航到一个特定的类,等等。

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

      此方法适用于任何Windows窗体应用程序。您需要重写wndproc方法。要查看方式,请检查 The Code Project 文章 Use WM_COPYDATA to send data to/from C++ and C# Windows processes .

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

    3. 在应用程序中,公开可编程的COM服务器对象。这正是Microsoft向应用程序公开Office功能的方式。Office Automation允许任何具有COM功能的程序(C, VBScript , PowerShell ,perl、php等)以“驱动”Office应用程序。此时,Office应用程序可见。这种方法还需要Windows窗体应用程序中的其他代码;具体来说,您必须宿主一个COM对象并将其连接到UI层。如果您希望超级用户拥有最大的灵活性,这可能是更好的选择——他们可以编写自己的脚本来驱动该组件。

    我相信还有其他的选择。

        4
  •  0
  •   Peter Mortensen icecrime    13 年前

    我记得看到 IronPython 在从Python命令行界面控制Windows窗体的演示中使用( IDLE )

    编辑: 我找不到原来的视频,但这一个应该显示什么是可能的,没有太多的努力。 See this video 跳到19点。

        5
  •  0
  •   Peter Mortensen icecrime    13 年前

    这是可能的。您必须研究Windows窗体的线程,可能需要使用单独的 application domain 在同一过程中。您可以考虑创建代理对象(一种继承MarshalByRefObject的消息类)。

        6
  •  0
  •   Peter Mortensen icecrime    13 年前

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

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

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