x64 Windows で Poderosa のターミナルをタブで次々と開く方法(解決編)
.NET Frameworkアプリを32bitで動作するようにする*1
前回(調査編)、64bitと32bitの違いで動作に問題があることがわかりました。 となるとOSSのPoderosaでとれる対応は2つありそうです。
対応策
- ソースに手を入れてWin32 APIの所を改修する
- 32bitモードで動かすようにする
手抜きな僕は、後者を選択しました(^_^)
Visual Studioの操作手順
環境
- Windows 8.1 x64
- Visual Studio Express 2013 for Windows Desktop
- Poderosaのソース4.3.8bを使用
ソースをDLして開く!
- poderosa.sln をダブルクリック、プロジェクトの変換が必要だが全部お任せ
構成マネージャからx86ビルドを追加する
右のソリューションエクスプローラーを右クリック、「構成マネージャー」を選択
構成マネージャーの「アクティブ ソリューション プラットフォーム」から「<新規作成..>」を選択する
新しいプラットフォームの選択で「x86」を選択してOK!
プラットフォームがx86になります!
後はビルド!!! おそらく問題なくビルドできると思います!
ビルドができたら、「Poderosa-4.3.8b\Executable\obj\x86\Release」の中に「Poderosa.exe」があるのでいつも使っているPoderosa.exeに上書き! (バックアップはお忘れなく!)
後は32bitプロセスで動いているのか確認!
晴れて、Poderosaが64bitモードで動きました! Poderosa(x64).exeが今回ビルドしたの64bit版で動くPoderosaです! 通常のPoderosa.exeは32bitで動いています。
ここまでやると、こちらのバッチファイルでポンポンと新しいタブで開く元の挙動になりました!
あとがき
今回はPoderosaでしたが.NETのアプリケーションには同じような問題があるかもしれない。 .NETアプリすべてを32bitで動かすような設定もあるようなので確認したい
*1:2014年09月03日にQiitaに投稿した記事です。
x64 Windows で Poderosa のターミナルをタブで次々と開く方法(調査編)
たくさんのサーバに一挙ログイン!してたのに・・・*1
Windows7(x86)からWindows8.1(x64)にアップグレードしたら、Poderosaの「-open」オプションを使ってひとつのPoderosaプロセスで複数のタブが起動できなくなった。
元々batファイルで以下の様に指定してた。 D:\soft\Poderosa に Poderosa本体がインストールされています D:\soft\Poderosa\gts に gtsファイルが複数置いてあります
とあるディレクトリにあるgtsファイルを読み込んで一気に開くbatファイルは以下の通り用意してました
set PODEROSA_ROOT=D:\soft\Poderosa\ set PODEROSA_GTS=D:\soft\Poderosa\gts\ set PODEROSA_EXE=%PODEROSA_ROOT%Poderosa.exe set PODEROSA_CONF=%PODEROSA_GTS%conf start "Poderosa" /D %PODEROSA_ROOT% %PODEROSA_EXE% Rem 以下の2秒は環境による。ウィンドウができ終わるまで待つのがみそ。 timeout 2 Rem dirかまして*.gtsを全部PoderosaでOpenする! for /f %%i in ('dir /b %PODEROSA_GTS%*.gts') do "%PODEROSA_EXE%" -open "%PODEROSA_GTS%%%i"
でも、これがWindows8.1(x64)に移行したら動かなくなりました。。。 batファイルは動くのですが、gtsファイルの分だけPoderosa.exeが起動してしまい タブにならず、たくさんのウィンドウが表示されるようになってしまいました。
当初は、Windows7からWindows8.1に移行したためだと考えていたのですが、調査したところx86からx64になったため挙動が変わったって事だったのですが、気がつくまでの顛末を書いておきたいと思いました。
Poderosaのソースをみてみる
とりあえず"-open"の引数を処理しているところのソース追いかけてみた。
//コマンドライン引数を読む int i = 0; while (i < args.Length) { string t = args[i]; string v = i < args.Length - 1 ? args[i + 1] : ""; switch (t) { case "-p": case "--profile": preference_home = ResolveProfileDirectory(v); i += 2; break; case "-a": case "--addasm": pm.AddAssembly(home_directory, v.Split(';')); i += 2; break; case "-r": case "--remasm": pm.RemoveAssembly(home_directory, v.Split(';')); i += 2; break; case "-open": open_file = v; i += 2; break; default: i++; break; } if (open_file != null && TryToSendOpenFileMessage(open_file)) return null; //別インスタンスに送信
ふむふむ。。。どうやら、TryToSendOpenFileMessage()が何らかの理由で上手くいってないに違いない。 さらに調査を進めると・・・
//別インスタンスへの送信を試みる。ショートカットを開いたときの多重起動に関するところで。 private static bool TryToSendOpenFileMessage(string filename) { //ウィンドウを見つける unsafe { //find target IntPtr hwnd = Win32.FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, null); char[] name = new char[256]; char[] mf = new char[256]; while (hwnd != IntPtr.Zero) { int len = Win32.GetWindowText(hwnd, name, 256); if (new string(name, 0, len).IndexOf("Poderosa") != -1) { //Window Classを確認するとか何とかすべきかも、だが if (TryToSendOpenFileMessage(hwnd, filename)) return true; } hwnd = Win32.FindWindowEx(IntPtr.Zero, hwnd, null, null); } return false; } }
原因は64bitプロセス内でWin32 APIのFindWindowEx()を使っても64bitプロセスのウィンドウは見つからないこと!
ここのソース【Win32.FindWindowEx】を見たときに「ああ、OSのバージョンじゃなくて、x86をx64にしたせいだ!」ってひらめきました! ちょっと調べるとたくさん出てくる出てくる。 ● 32bit プロセスは 64bit プロセスを見つけられない - Life like a clown
.Net Frameworkで動くPoderosaは64bitで動いているので、Win32 APIであるFindWindowEx()ではウィンドウが見つからないため、新規に起動されていたわけですね。
やっと挙動に納得。次は対応策を検討せねば。。。
*1:2014年08月22日にQiitaに投稿した記事です。