- PR -

Windowsアプリケーションのコマンドラインからの起動

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-02-06 20:20
引用:

赤いんげんさんの書き込み(2007-02-05 00:57)より:
がしかし、EXEファイルをダブルクリックして起動すると、一度DOSプロンプトが開いて、その上でメインFORMが表示されるようになりました。(当たり前かもしれませんが。)


あ。。。失礼。私は逆で、バッチ処理する途中のコマンドなんだけど、ウインドウもあった方が便利だな、、、だったので、コマンドプロンプト上からしか実行していませんでした(^-^;
_________________
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-02-06 21:46
こんばんは。

赤いんげんさんに特別に
私が発見した裏ワザをこっそりと教えちゃいます。
#ヒ・・ミ・・ツ・・ですよ(^_-)

(注意)Visual Studio2003で確認しています。

1.先ず、Windowsアプリケーションで普通に
  Console.WriteLineなどでコンソール出力を記述してビルド。
  特になんにもする必要ありません。

2.次のファイル(私のPCの場合)を、ビルドした実行ファイルと同じフォルダへコピー。
  "C:¥Program Files¥Microsoft Visual Studio .NET 2003¥Common7¥IDE¥devenv.com"

3.コピーしたファイルの名前をビルドしたファイル名に変更します。
  ※拡張子は変更しないこと!
  例えばビルドした実行ファイルがABC.exeの場合、
  コピーしたファイル名をABC.comへ変更します。

4.後は、コマンドラインからコマンドを入力してみてください。
  ※拡張子はあえて省略してください。
  >ABC[RET]

どうですか?うまくいったでしょ??

渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-02-06 22:41
引用:

2.次のファイル(私のPCの場合)を、ビルドした実行ファイルと同じフォルダへコピー。
  "C:¥Program Files¥Microsoft Visual Studio .NET 2003¥Common7¥IDE¥devenv.com"



再配布不可でしょ?
開発者の手元でだけ動作しても意味無いと思う。

それとも、devenv.com が何をやってるのか調べて、同じものを作れば?ってことなんでしょうか?
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-02-06 22:46
こんばんは。

引用:

渋木宏明(ひどり)さんの書き込み (2007-02-06 22:41) より:
再配布不可でしょ?


だからヒミツだったんですけども。

引用:

それとも、devenv.com が何をやってるのか調べて、同じものを作れば?ってことなんでしょうか?



自作できなくもなさそうですね。
つまり直接コンソールに出力できないなら、
パイプを使って代わりに出力してあげるプログラムを作って上げましょうという感じです。

Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-02-06 22:59
こんばんは。

引用:

Tdnr_Symの書き込み (2007-02-06 22:46) より:

自作できなくもなさそうですね。
つまり直接コンソールに出力できないなら、
パイプを使って代わりに出力してあげるプログラムを作って上げましょうという感じです。



なぜパイプなのか分からない方もいらっしゃるかもしれないので
簡単に実証してみますと…
MOREコマンドとパイプでつなげてみてください。
ちゃんとコンソールに出力できるでしょ?

>ABC.exe | MORE
赤いんげん
会議室デビュー日: 2006/08/29
投稿数: 10
お住まい・勤務地: 東京都
投稿日時: 2007-02-07 00:58
皆様

帰宅してみたら、多くのレスがついていてビックリです!
色々な可能性を探って頂いて、大変うれしいです。
すでに私がついていけないレベルの話になっているような気がしますが・・・
(レスが多いので各レスへの返答は割愛させて頂きます。すいません。)

今回、色々と出てきた案について私のAPに適用する場合について考えてみました。

■案1.本体DLLとコンソールUIとGUIの3つのパーツに分ける。
 → 本来こういう作りにすべきだったんですね・・・ただ恥ずかしながら、既存APが
   メインロジックとFORMの間で共有変数を使っていたりと密な結合になっています。
   今から全てのコードを分割すると結構大変な作業となってしまうので、
   今回は見送りたいと思います・・・すいません。

■案2.AttachConsole関数を使用する
 → 魅力的な関数ですが、最低でもWin2000には対応させたいと思っていますので見送り。

■案3.devenv.comを使用する
 → 再配布するAPなので見送り。

■案4.パイプを使って代わりに出力するAPを自作
 → 何やら私にとっては難しそうです・・・結局は案5と同じ?

■案5.MOREコマンドをパイプで繋げて出力
 → なるほど、こんなに簡単にできるんですね。コンソール上に出力できました。
   ちょっとトリッキーな案ですが、私の求める要件は満たせています。
   以下の2点が気になりますが、注意事項として記述しておきます。
 
   A.出力が1ページ分を超えると「-- MORE --」が出力されてそこで一旦出力が止まる。
   B.「Ctrl+C」を押しても、DOSプロンプトを閉じても、APP.EXEが止まらない。

あと、ここまで書いていて今更なんですが、「DOSプロンプトから起動できて、
出力メッセージが確認できる」ということが実現できればいいので、
出力メッセージを第2引数で与えられたファイルに書き出すという作りに
してもいいかなと考えています。

あとはユーザの反応を見ながら作成方法を決めたいと思います。
皆様どうもありがとうございました。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-02-07 09:02
おはようございます。

引用:

赤いんげんさんの書き込み (2007-02-07 00:58) より:

■案4.パイプを使って代わりに出力するAPを自作
 → 何やら私にとっては難しそうです・・・結局は案5と同じ?



CreatePipeというWinAPIを使ったサンプルがネット上に転がっているので
ほぼそのまま流用すればできるでしょう。
時間があれば私がつくってもよいですが…(C/C++ですけど)

引用:

■案5.MOREコマンドをパイプで繋げて出力
 → なるほど、こんなに簡単にできるんですね。コンソール上に出力できました。
   ちょっとトリッキーな案ですが、私の求める要件は満たせています。
   以下の2点が気になりますが、注意事項として記述しておきます。
 
   A.出力が1ページ分を超えると「-- MORE --」が出力されてそこで一旦出力が止まる。
   B.「Ctrl+C」を押しても、DOSプロンプトを閉じても、APP.EXEが止まらない。



簡単に実証してみただけで、そのまま使うことを意図したわけではないです。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-02-07 11:28
こんにちは。

引用:

Tdnr_Symの書き込み (2007-02-07 09:02) より:

CreatePipeというWinAPIを使ったサンプルがネット上に転がっているので
ほぼそのまま流用すればできるでしょう。
時間があれば私がつくってもよいですが…(C/C++ですけど)



やっぱりCreatePipeを使うのは個人的に飽きたので、
VB.NETを使ってざっと作ってみました。
#赤いんげんさんにはもう必要なさそうですけども…

※devenv.comと同じように実行ファイル名を変更して使ってみてください。
#マズイところもあると思いますが、サンプルということで…

コード:
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Class PipeOut

    Shared Sub Main()

        ' コマンドライン引数の取得
        Dim cmdline As String() = Environment.GetCommandLineArgs()

        ' 自分のExe名
        Dim strMyExeName As New System.Text.StringBuilder(1000)
        GetModuleFileName(IntPtr.Zero, strMyExeName, strMyExeName.Capacity)

        ' キックするExe名
        Dim strKickExeName As String = System.IO.Path.ChangeExtension(strMyExeName.ToString(), ".exe")

        ' キックするExe名が自分自身の場合は、キックせず終了
        If String.Compare(strMyExeName.ToString(), strKickExeName, True) = 0 Then
            Exit Sub
        End If

        ' キックするExeに引き渡す引数
        Dim args As String
        For i As Integer = 1 To cmdline.Length - 1
            args += " " + cmdline(i)
        Next

        ' 標準出力のリダイレクトを有効にする
        Dim proc As New Process
        proc.StartInfo.UseShellExecute = False
        proc.StartInfo.RedirectStandardOutput = True
        proc.StartInfo.FileName = strKickExeName
        proc.StartInfo.Arguments = args

        Try
            proc.Start()
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
            Exit Sub
        End Try

        ' キックしたEXEの標準出力をパイプで読み出しコンソールへ書き込み
        Dim reader As System.IO.StreamReader = proc.StandardOutput
        Do
            Do While reader.Peek > 0

                Dim buf(1000) As Char
                Dim len As Integer

                len = reader.Read(buf, 0, buf.Length)

                Dim strRead As New String(buf, 0, len)
                Console.Write(strRead)
            Loop

        Loop Until proc.WaitForExit(100)

        ' 最後まで
        Console.Write(reader.ReadToEnd())

    End Sub

    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Shared Function GetModuleFileName(ByVal hModule As IntPtr, ByVal lpFilename As System.Text.StringBuilder, ByVal nSize As Integer) As System.Int32
    End Function

End Class



スキルアップ/キャリアアップ(JOB@IT)