monoの開発ブログ

プログラム開発の記録

Archive for 9月, 2009

64bit対応なフックを使ったアプリの作り方

without comments

拙作ExUtilVのように、32bitと64bitのどちらの環境でも動作するフックを使ったアプリケーションの作り方を説明したいと思います。

まず、大前提としてWindowsでは32bitアプリは64bitアプリにフックをインストールできませんし、64bitアプリは32bitアプリにフックをインストールできません。
そのため、32bitアプリと64bitアプリの両方にフックをインストールしたい場合、同じ動作をする32bitのバイナリと64bitのバイナリを用意して両方を実行する必要があります。
幸い、普段からポインタや型の大きさを意識してコードを記述していれば32bit、64bitの両方でまったく同じコードを利用できるので、64bit対応は意外と簡単に実現可能なのです。

しかし、利用者に2つアプリを起動してもらうというのはなんだか格好悪いですよね。
そこで、ExUtilVでは32bit版のプログラムに64bit版を自動的に起動する処理やユーザインターフェイスを内蔵し、64bit版のプログラムはフックを行うだけという構造をとっています。
このようにすることで、32bit版Windows上では32bit版のプログラム単体で完結し、64bit版Windows上では2つのプロセスで動作するようにできます。
タスクマネージャを見るとプロセスが2つあってやっぱり微妙なのですが、利用者が不便を被るようなことはなくせます。

ここからは実現方法を追ってみます。
まず、64bit版Windowsかどうかを判定するコードを記述します。
素直にOSのバージョンを調べればいいのでしょうが、ここでは自分がWOW64環境で動作しているプロセスであるかどうかで判定しています。
先述の通り32bit、64bitのどちらのOSを利用していても、始めに利用者が起動するのは32bit版のプログラムですので、WOW64環境である==64bit版Windowsを利用していると判断できます。
実際のコードは以下の通りです。

bool IsWow64() {
  typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
  LPFN_ISWOW64PROCESS fnIsWow64Process;

  // IsWow64Process関数が存在するかどうか調べる
  fnIsWow64Process = reinterpret_cast<LPFN_ISWOW64PROCESS>(
    GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process"));
  if(fnIsWow64Process) {
    // 存在する場合、呼び出して確認
    BOOL isWow64 = FALSE;
    return !!(fnIsWow64Process(GetCurrentProcess(), &isWow64) && isWow64);
  }
  // 存在しない場合は確実に非WOW64環境
  return false;
}

そして、この関数を呼び出した結果がtrueだった場合には64bit版のプログラムを起動します。

#ifndef WIN64
if(IsWow64()) {
  STARTUPINFO lpStartupInfo;
  GetStartupInfo(&lpStartupInfo);
  PROCESS_INFORMATION lpProcessInformation;
  CreateProcess(_T("64bit版プログラム"),
    0, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0,
    &lpStartupInfo, &lpProcessInformation);
}
#endif

最後に、利用者がプログラムを終了しようとした場合には何らかの手段で64bit版のプロセスにもそのことを通知しましょう。
これにはいろいろな方法があると思いますが、ExUtilVでは非表示のウィンドウにWM_CLOSEを送信しています。

長々と書いてみましたが、要するに64bitのアプリが少なくて不便なのでみんなもいっぱい作ってね、ということです。

# ただし、このような構造になるのは次回公開するバージョンからの予定です。
# 現在公開している0.0.10のソースを読んでもこのようにはなっていないので、あしからず。

Written by mono

9月 13th, 2009 at 9:20 pm

Posted in Windows

Tagged with ,

同じ設定で新規作成するEmEditorのマクロ

without comments

現在開いているドキュメントと同じ設定、エンコーディングでドキュメントを新規作成するマクロを公開しました。
かなり昔に公式フォーラムに投稿したものです。

ダウンロード

プログラム開発など同じ形式のファイルを多数作成するような場合には、このような挙動だと便利なのではないでしょうか。
ちなみに、うちではキーボードのCtrl+Nを置き換えて利用しています。

Written by mono

9月 13th, 2009 at 3:09 am

Posted in EmEditor

Tagged with ,

ExUtilV version 0.0.10

without comments

ExUtilVを更新しました。

ダウンロード / 詳細

今回はShiftキーを押しながらコンテキストメニューを開いたときに表示される便利なコマンドを、常時表示する機能を追加しました。
ぜひお試しください。

Written by mono

9月 10th, 2009 at 3:26 pm

Posted in ExUtilV, Windows

Tagged with ,