web-dev-qa-db-ja.com

GUIとコマンドラインの両方のC#アプリケーション

現在、GUIを備えたアプリケーションがあります。

コマンドラインからこの同じアプリケーションを使用することは可能でしょうか(GUIなしで、パラメーターを使用して)。

または、コマンドラインツール用に別個の.exe(およびアプリケーション)を作成する必要がありますか?

45
PeeHaa
  1. プロジェクトのプロパティを編集して、アプリを「コンソールアプリケーション」ではなく「Windowsアプリケーション」にします。この方法でもコマンドラインパラメータを受け入れることができます。これを行わないと、アプリのアイコンをダブルクリックしたときにコンソールウィンドウがポップアップ表示されます。
  2. Main関数がコマンドラインパラメーターを受け入れることを確認してください。
  3. コマンドラインパラメーターを取得する場合は、ウィンドウを表示しないでください。

以下に簡単な例を示します。

[STAThread]
static void Main(string[] args)
{
    if(args.Length == 0)
    {
        Application.Run(new MyMainForm());
    }
    else
    {
        // Do command line/silent logic here...
    }
}

アプリがまだサイレント処理を行うように構造化されていない場合(すべてのロジックがWinFormコードに詰まっている場合)、 ala CharithJの回答でサイレント処理をハックする を使用できます。

OPによる編集答えをハイジャックしてすみません、Merlyn。他の人のためにここにすべての情報が欲しいだけです。

WinFormsアプリでコンソールに書き込むには、次のようにします。

static class Program
{
    // defines for commandline output
    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(int dwProcessId);
    private const int ATTACH_PARENT_PROCESS = -1;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // redirect console output to parent process;
        // must be before any calls to Console.WriteLine()
        AttachConsole(ATTACH_PARENT_PROCESS);

        if (args.Length > 0)
        {
            Console.WriteLine("Yay! I have just created a commandline tool.");
            // sending the enter key is not really needed, but otherwise the user thinks the app is still running by looking at the commandline. The enter key takes care of displaying the Prompt again.
            System.Windows.Forms.SendKeys.SendWait("{ENTER}");
            Application.Exit();
        }
        else
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new QrCodeSampleApp());
        }
    }
}
59

Program.csクラスでは、Mainメソッドはそのままにしますが、string[] Argsをメインフォームに追加します。例えば...

    [STAThread]
    static void Main(string[] Args)
    {
        ....
        Application.Run(new mainform(Args));
    }

Mainform.csコンストラクター内

    public mainform(string[] Args)
    {
        InitializeComponent();

        if (Args.Length > 0)
         {
             // Do what you want to do as command line application.
             // You can hide the form and do processing silently.
             // Remember to close the form after processing.
         }
    }
10
CharithJ

私はC#プログラミングに慣れていません。しかし、OPとMerlynからのコードヒントを即興で作成しました。コードヒントを使用するときに直面した問題は、app.exeをダブルクリックしてapp.exeを呼び出すとき、またはCMDから呼び出すときに引数の長さが異なることでした。 app.exeがCMDからCLIとして実行されると、app.exe自体が最初の引数になります。以下はapp.exeのGUIダブルクリックとCMDからのCLIの両方で満足に動作する私の即興コードです。

[STAThread]
    static void Main(/*string[] args*/)
    {
        string[] args = Environment.GetCommandLineArgs();
        Console.WriteLine(args.Length);
        if (args.Length <= 1)
        {
            //calling gui part
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new ACVSAppForm());
        }
        else
        {
            //calling cli part                
            string opt = args[1];
            //Console.WriteLine(args[0]);                
            if(opt == "LastBuild")
            {
                if(args.Length == 3)
                {
                    var defSettings = Properties.Settings.Default;
                    defSettings.CIBuildHistPath = args[2];
                }
                else
                {
                    //
                }
                CIBuildParser cibuildlst = new CIBuildParser();
                cibuildlst.XMLParser();
            }
        }

    }

これが誰かの助けになることを願っています。私のソリューションの唯一の欠点は、app.exeをGUIとして実行すると、コンソール出力ウィンドウとしてCMDが開くことです。しかし、これは私の仕事には問題ありません。

0
MFz

コメントするのに十分なポイントがありません。 mingwを使用してプログラムを呼び出すときに[DllImport( "kernel32.dll")]がコンソールに書き込む必要がないという受け入れられたソリューションに追加したかったのですが、これはWindows/DOSの問題のようです。

0
user1529413