簡體   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