首页 文章

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

提问于
浏览
8

我已经阅读了一些关于组合Windows窗体和控制台应用程序的程序的主题,但似乎我的问题还没有解决 . 是否可以从cmd-line运行程序并能够通过表单和cmd-line命令控制应用程序?它的意思是:

  • 为应用程序的普通用户通过(Windows窗体)表单控制应用程序,

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

我知道我想要的东西是非常重要的,它可能意味着很多工作,但我仍然想知道如何正确地做到这一点 .

6 回答

  • 1

    这并不难,只需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();
      }
    
  • 5

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

    您也可以自己创建一个命令行可执行文件并与Windows窗体库链接以使用它们 .

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

  • 1

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

    • 使用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窗体的进度监视器,可以直观地显示长时间运行的测试的进度 .

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

    我相信还有其他选择 .

  • 0

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

    Edit: 我找不到原始视频,但是这个应该显示出可能没有太多努力的可能性 . See this video并跳到19:00 .

  • 0

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

  • 0

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

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

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

相关问题