先日プログラムが動くことを優先して製作したプログラムを、Visual Studio 2022で、ちゃんとブロック化したり、必要ファイルがない場合にテンプレートを作ったりできるように改造しようとして苦戦中。
Visual Basic 2019, 2022 のデバッグ機能には、出来上がった .exe ファイルを引数付きで実行する場合をエミュレーションできるように、コマンドライン引数機能があります。これは便利。
以下は、VS2019の設定画面。
VS2022では設定画面がちょっと違うものの、同様にコマンド引数を設定できます。
コマンドラインツールを作っているとき、デバッグ中はこの機能を使ってます。
ところが、突然この機能が働いたり働かなくなったりして困っているところ。
コンソールアプリをデバッグしようとすると、デバッグを始めた後(デフォルト設定なら、画面出力があれば)コマンド画面が開いて、プログラムが最後まで走った後、何かキーを押すと画面を閉じることが出来ます。
今回もそうやってデバッグしていたんですが、ソースを編集しているうちに、画面が勝手に閉じてしまうようになりました。
最初、何が起きているのか、原因が何なのかがわからなかったので、ブレークポイントをプログラム最終行にセットしてデバッグしたところ、変数に値が入っているべきところに入っていないことに気づきました。変数に入る値は、コマンド引数から渡されるので、コマンド引数を処理する過程でロストしているのか、引数を持ってきていないのか観察してみたところ、どうも、デバッグを開始した時点で渡されていないような動き。私のソースがおかしいのじゃなくて、Visual Studio 側がプログラムにパラメータを渡していない感じ。
ソースを編集してこうなったから、ソースに不都合な記述があることは間違いないので、切り分けていったところ必要なファイルが存在しているかどうかを確かめ、ファイルが無かった場合に、ひな型ファイルを作るという流れでファイルを作った場合、コマンド画面が消えてしまい、引数も渡されていないことに気が付きました。
デバッグ用のビルドは成功しているので、デバッグ環境からではなく、コマンドプロンプトを起動して、プログラムを実行してみたところ、コマンドライン引数は問題なく渡されて、必要な情報が画面に表示されました。
ファイルが開きっぱなしになってIOが開いていなくて引数を渡せない状態なんじゃないかと思うのですが、何をどう確認して、どう対処すればいいかがわからない!
実行ファイルと同じフォルダーに config.ini ファイルが無かったら作って、コメント行を書き込んで、デフォルト設定ファイルっぽいものを作るサブルーチンを書きました。
Sub chk_config() 'Dim cmds As String() = System.Environment.GetCommandLineArgs() 'If File.Exists(Path.GetDirectoryName(cmds(0)) & "\config.ini") Then If File.Exists(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase & "\config.ini") Then Console.WriteLine("config.iniあり") Else Console.WriteLine("config.iniなし、ファイル作成") 'Dim writer As FileStream = File.Create(Path.GetDirectoryName(cmds(0)) & "\config.ini") Using writer = New StreamWriter(".\config.ini", True) writer.WriteLine("# サンプル config.ini") writer.WriteLine("# すべて半角文字で記述のこと。") writer.WriteLine("# ""' や "" で文字を囲まない。") writer.WriteLine("# 各行の文字間にスペースは入れないこと。空白行はOK。") writer.WriteLine("mailaddr=") writer.WriteLine("password=") writer.WriteLine("# ffmpeg.exe を同一フォルダーに置く場合は、ffmpeg_path をコメント行にすること") writer.WriteLine("ffmpeg_path=.\ffmpeg.exe") End Using End If End Sub
もし、config.ini ファイルが存在していればデバッグ環境の動作は問題なし。ところが、config.ini が存在していなくて、上記の Else の方を走ってしまうと、コマンドライン引数が渡されなくて、プログラム終了時にコマンド画面が勝手に消えてしまうという現象になります。きっとファイルが開きっぱなしになってるんじゃないか?と、いろいろPATHを知るためのメソッドを変えてみたり、行をくわえてみたりしたのですけど、関係ないみたい。
というか、一度この現象になると、一度プロジェクトかVS2022を終了させて config.ini を作っておかないと、絶対に復旧しないので面倒です。
プログラムの中のどこかに、引数を置いておいて、デバッグ中はそこからパラメータを引っ張ってくるようにすれば回避できることはわかっているので、これが解決しないとプログラムを作れないというわけではありません。最終段階で、書き換えればいいだけですから。
Visual Studio 2019 では試しておらず、ソースの書き方の問題なのか、VB.NETとVisual Studioの組み合わせの問題なのか、そこら辺は切り分けてません。
回避策で進めていると、問題発生条件を忘れてしまいそうなので、そのためのメモ。
明日からは、ここは回避して、次に進もう!