none
コマンド プロンプトから実行されたかどうか 知る方法はありますか? RRS feed

  • 質問

  •  一つのアプリケーションで、コマンド プロンプトから呼び出された場合は コンソール出力、その他の場合はフォームを開くように使い分けたいのですが、アプリケーションがどちらで呼び出されているのか知る方法は あるのでしょうか?

     よろしくお願いします。

    2010年2月3日 11:09

回答

  • 標準入出力のストリームの種類が違ってるみたいだからそれで判定してみる。

    static void Main()
    {
        if(System.Console.In is System.IO.StreamReader)
        {
            MessageBox.Show("Window");
        }
        else
        {
            MessageBox.Show("Console");               
        }
    }

    #もっとましな判別方法はありそうですが
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月3日 13:03
  • この話題、考えたことはありますが、判定だけでは解決しません。

    VBやC#でWindowsアプリケーションを選択した場合、たとえコンソールから起動されてもすぐに切り離してしまいます。そのため、コンソールに対して出力できません。
    逆にコンソールアプリケーションを選択した場合、コマンドプロンプトから起動された場合にはうまくいきますが、Explorerなどから起動された場合、自動的にコンソールを作成してしまいます。
    # 質問にはありませんが、そういう動作はきっと避けたいかと思います。

    となると、C++/CLIでスタートアップルーチンを自作するしかないのかなぁ、と思います。
    思っただけで作ったことはありません…。
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月3日 13:16
  • やりたいことに似ているが違うものとして、US のフォーラムにあるスレッドを紹介しておきます。
    http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/fd89cf64-eab4-4cc5-8f35-74ec848d8a60/


    コンソールオプションがついていたら、コンソールに対して入出力をかけますが、恐らく期待する動きと異なります。
    例えば、コマンド打った後、次のプロンプトが出てしまっているといった具合です。

    出力例:
    C:\> test.exe
    C:\> hello. It looks like you started me from an existing console.

    ※太字強調部分が期待しない結果だと予想しています。
    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月3日 14:06
    モデレータ
  • なのですが、コンソール出力しようとすると コマンド プロンプトから起動した場合でも 別のコンソールを開いて そこに出力するらしく、開いた元の コマンド プロンプト画面には 出力できませんでした。
    そこはAttachConsole()すれば同じコンソールに出力できます。

    hoge.exe > con でもできます。

    いずれにせよ、コマンドプロンプトが待ち合わせしないですぐ復帰するので、使いにくくて駄目でしょう。

    hoge.exe | more なら、まだましですが、呼び出しを変えるくらいなら別々のほうが楽です。
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月4日 3:18
  •  残念ながら、使っている言語が DllImport のできない JScript なので、外部 API が
    使えないんです; ←最初に書いとけ
    JScriptから使えなくもないですが、それはさておき

     差し当たり、コンソール ベースにして スイッチをコマンド ラインで指定した時だけ フォームを開く…というのと、別々のプログラムとして作るのとで、使い勝手を比べてみようと思います。
    このときの区別は、

    Process.GetCurrentProcess().MainWindowHandle

    でできるのではないかと。
    • 回答としてマーク にふてぃ 2010年2月15日 11:45
    2010年2月4日 12:57

すべての返信

  • 標準入出力のストリームの種類が違ってるみたいだからそれで判定してみる。

    static void Main()
    {
        if(System.Console.In is System.IO.StreamReader)
        {
            MessageBox.Show("Window");
        }
        else
        {
            MessageBox.Show("Console");               
        }
    }

    #もっとましな判別方法はありそうですが
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月3日 13:03
  • この話題、考えたことはありますが、判定だけでは解決しません。

    VBやC#でWindowsアプリケーションを選択した場合、たとえコンソールから起動されてもすぐに切り離してしまいます。そのため、コンソールに対して出力できません。
    逆にコンソールアプリケーションを選択した場合、コマンドプロンプトから起動された場合にはうまくいきますが、Explorerなどから起動された場合、自動的にコンソールを作成してしまいます。
    # 質問にはありませんが、そういう動作はきっと避けたいかと思います。

    となると、C++/CLIでスタートアップルーチンを自作するしかないのかなぁ、と思います。
    思っただけで作ったことはありません…。
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月3日 13:16
  • やりたいことに似ているが違うものとして、US のフォーラムにあるスレッドを紹介しておきます。
    http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/fd89cf64-eab4-4cc5-8f35-74ec848d8a60/


    コンソールオプションがついていたら、コンソールに対して入出力をかけますが、恐らく期待する動きと異なります。
    例えば、コマンド打った後、次のプロンプトが出てしまっているといった具合です。

    出力例:
    C:\> test.exe
    C:\> hello. It looks like you started me from an existing console.

    ※太字強調部分が期待しない結果だと予想しています。
    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月3日 14:06
    モデレータ
  •  回答ありがとうございます。

    ストリームで判断する方法を試してみましたが、佐祐理さん、Azulean さんの仰るように、コンパイル時のコンソール アプリケーションかフォーム アプリケーションかの選択によって、余分なコンソールが開いたりする問題が出ました;

    ■コンソール アプリケーションとしてコンパイルした場合
    ・コマンド プロンプトから起動すると 入力ストリームは TextReader
    ・直接起動しても コマンド プロンプトが開かれてから呼び出されるので、入力ストリームは TextReader
    …で判別できず、フォーム アプリケーションに切り換えられませんでした。

    ■フォーム アプリケーションとしてコンパイルした場合
    ・コマンド プロンプトから起動すると 入力ストリームは TextReader
    ・直接起動すると 入力ストリームは StreamReader.Null
    なのですが、コンソール出力しようとすると コマンド プロンプトから起動した場合でも 別のコンソールを開いて そこに出力するらしく、開いた元の コマンド プロンプト画面には 出力できませんでした。

     単一アプリケーションとしてコンパイルできないなら、Process 呼び出しなどでフォームを開くより、コンソール/フォーム用で 別々に作ってしまった方が 簡単で軽量かも知れませんね(汗)
    2010年2月3日 19:59
  • なのですが、コンソール出力しようとすると コマンド プロンプトから起動した場合でも 別のコンソールを開いて そこに出力するらしく、開いた元の コマンド プロンプト画面には 出力できませんでした。
    そこはAttachConsole()すれば同じコンソールに出力できます。

    hoge.exe > con でもできます。

    いずれにせよ、コマンドプロンプトが待ち合わせしないですぐ復帰するので、使いにくくて駄目でしょう。

    hoge.exe | more なら、まだましですが、呼び出しを変えるくらいなら別々のほうが楽です。
    • 回答としてマーク にふてぃ 2010年2月4日 9:50
    2010年2月4日 3:18
  •  残念ながら、使っている言語が DllImport のできない JScript なので、外部 API が
    使えないんです; ←最初に書いとけ

     差し当たり、コンソール ベースにして スイッチをコマンド ラインで指定した時だけ フォームを開く…というのと、別々のプログラムとして作るのとで、使い勝手を比べてみようと思います。

      回答を下さった皆様、ありがとうございました。
    2010年2月4日 9:49
  •  残念ながら、使っている言語が DllImport のできない JScript なので、外部 API が
    使えないんです; ←最初に書いとけ
    JScriptから使えなくもないですが、それはさておき

     差し当たり、コンソール ベースにして スイッチをコマンド ラインで指定した時だけ フォームを開く…というのと、別々のプログラムとして作るのとで、使い勝手を比べてみようと思います。
    このときの区別は、

    Process.GetCurrentProcess().MainWindowHandle

    でできるのではないかと。
    • 回答としてマーク にふてぃ 2010年2月15日 11:45
    2010年2月4日 12:57
  • >JScriptから使えなくもないですが

     (-x-;) …ェ、そうだったんですか。
    不勉強でスイマセン;

    コンソール アプリケーションでコンパイルしたら、教えて頂いたとおり、MainWindowHandle から判別できました。
     ありがとうございます^^

    (ちなみに、フォーム アプリケーションとしてコンパイルすると MainWindowHandle = IntPtr.Zero で固定でした)
    2010年2月15日 11:54