Antoine.st 2005-12

2005-12-30

Remote Desktop

ちょっと処理が終わらなかったので、リモートで接続できるようにして帰りました。あらら、これ、今の設定じゃ駄目じゃないですか。設定変更です。ちょいちょいっと、そんで [OK]ボタンをクリック。え? 再起動ですか。了解です。10 分くらい経ったら、また繋ぎましょうか。

...。 ...。 ...。

繋がらない...。

明日(って、もう今日か)、出勤です...。


2005-12-28

Font name

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts

にフォント名とフォントファイルの対応表(?)がありますよ、と。


2005-12-26

Trouble

XML の生成が...。どうしたもんかな。


2005-12-24

Merry X'mas

クリスマスでした。非キリスト者としては、あんまり関係ありませんけど。微妙に横幅 800px くらいに最適化してみたり。まだトップだけなので、他のページと統一感がありません。まぁ、横が長いと見づらいですからね。全体的なサイト更新は...。そのうちやりたいと思います。

#もう 3年になるしなぁ。

Favorite Song

最近お気に入りの曲がありまして。有線やら何やらで聞くだけだったので、誰が歌ってるのかも、タイトルも知らなかったのでした。で、詳しい人に聞いてみたところ、“不得不爱” (潘玮柏 featuring 高手弦子) というらしいと。いい曲です。ぜひ聞いてみてください。

PRADT ってサイトに歌詞があったのでメモ。じつは歌詞だけじゃなかったり。


2005-12-18

GetFileVersionInfo() without GlobalAlloc() - 2

手抜き版が不評だったので、もう少し真面目に。変数名もちゃんと直したので(Refactoring 機能は便利)、多少読みやすくなったかと。複数の結果が返ってくる実行ファイルが見当たらなかったので、ループがちゃんと動くかどうかは未確認。『俺』理論上は、うまく動くんじゃないかと思ってますけど。以下、気づいたこと。

  • Marshal.PtrToStructure() って、インテリセンスだと void を返す
  • Marshal.PtrToStructure() で配列に変換しようとすると、『引数なしのコンストラクタがない』というエラーが出る
  • たかだか 4バイトなので、構造体を使うまでもないかも

すいません。エラーチェックはやっぱり手抜きしてます。どなたか、Compact Framework で動くかどうか、複数の情報を持つ実行ファイル(って、あるのかどうか知りませんけど)の情報などなど、ご存知でしたら教えてもらえるとうれしいです。


  private void button1_Click(
    object sender,
    EventArgs e)
  {
    int returnValue;
    string fileName;
    int mustBeZero;
    int versionInfoSize;
    int structSize;
    uint numOfStruct;
    IntPtr versionInfo;
    IntPtr langAndCodepage;
    IntPtr tmpUse;
    LANGANDCODEPAGE[] langAndCodepageArray;
    string codePage;
    string lang;
    string subBlock;
    IntPtr productInfo;
    uint productInfoSize;
      
    fileName =
      @"C:\Windows\Sytem32\cmd.exe";
    mustBeZero = 0;
    numOfStruct = 0;
    structSize =
      Marshal.SizeOf(typeof(LANGANDCODEPAGE));
    langAndCodepage = IntPtr.Zero;

    versionInfoSize = 
      GetFileVersionInfoSize(
        fileName, 
        ref mustBeZero);
    versionInfo = 
      LocalAlloc(
        LMEM_MOVEABLE, 
        (uint)versionInfoSize);
    returnValue = 
      GetFileVersionInfo(
        fileName, 
        0, 
        versionInfoSize, 
        versionInfo);
    returnValue = 
      VerQueryValue(
        versionInfo,
        "\\VarFileInfo\\Translation",
        ref langAndCodepage,
        ref numOfStruct);
    langAndCodepageArray = 
      new LANGANDCODEPAGE[numOfStruct / structSize];
    tmpUse = new IntPtr(langAndCodepage.ToInt32());
    for (int j = 0; j < langAndCodepageArray.Length; j++) {
      tmpUse = 
        new IntPtr(
          langAndCodepage.ToInt32() + 
          (j * structSize));
      langAndCodepageArray[j] = 
        (LANGANDCODEPAGE)Marshal.PtrToStructure(
          tmpUse, 
          typeof(LANGANDCODEPAGE));
      codePage =
        langAndCodepageArray[j].wCodePage.ToString("x");
      codePage = codePage.PadLeft(4, '0');
      lang = 
        langAndCodepageArray[j].wLanguage.ToString("x");
      lang = lang.PadLeft(4, '0');
      subBlock =
        "\\StringFileInfo\\" + lang + codePage +
        "\\ProductName";
      productInfo = IntPtr.Zero;
      productInfoSize = 0;
      returnValue =
        VerQueryValue(
          versionInfo,
          subBlock, 
          ref productInfo,
          ref productInfoSize);
      if (productInfoSize != 0) {
        MessageBox.Show(
          Marshal.PtrToStringUni(productInfo));
      }
    }
    LocalFree(versionInfo);
  }


2005-12-14

GetFileVersionInfo() without GlobalAlloc()

まずは API の宣言。


  [
    DllImport(
    "version.dll", 
    EntryPoint="GetFileVersionInfoSizeW",  
    SetLastError=true,
    CharSet=CharSet.Unicode, 
    ExactSpelling=true,
    CallingConvention=CallingConvention.StdCall)
  ]
  public static extern int GetFileVersionInfoSize(
    String lptstrFilename, 
    ref int lpdwHandle
  );

  [
    DllImport(
    "version.dll",
    EntryPoint = "GetFileVersionInfoW",
    SetLastError = true,
    CharSet = CharSet.Unicode,
    ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)
  ]
  public static extern int GetFileVersionInfo(
    String lptstrFilename,
    int dwHandle,
    int dwLen,
    IntPtr lpData
  );

  [
    DllImport(
    "version.dll",
    EntryPoint = "VerQueryValueW",
    SetLastError = true,
    CharSet = CharSet.Unicode,
    ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)
  ]
  public static extern int VerQueryValue(
    IntPtr pBlock,
    string lpSubBlock,
    ref IntPtr lplpBuffer,
    ref uint puLen
  );

  [
    DllImport(
    "kernel32.dll",
    EntryPoint = "LocalAlloc",
    SetLastError = true,
    CharSet = CharSet.Unicode,
    ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)
  ]
  public static extern IntPtr LocalAlloc(
    uint uFlags, 
    uint uBytes
  );

  const uint LMEM_MOVEABLE = 0x0002;

  [
    DllImport(
    "kernel32.dll",
    EntryPoint = "LocalFree",
    SetLastError = true,
    CharSet = CharSet.Unicode,
    ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)
  ]
  public static extern IntPtr LocalFree(
    IntPtr hMem
  );

実際の呼び出しはこんな感じ。


  private void button1_Click(
    object sender,
    EventArgs e)
  {
    int ret;
    string s;
    int i;
    int size;
    uint usize;
    IntPtr h;
    IntPtr product;

    s = @"c:\windows\system32\cmd.exe";
    i = 0;
    product = IntPtr.Zero;
    usize = 0;

    size = GetFileVersionInfoSize(s, ref i);
    h = LocalAlloc(LMEM_MOVEABLE, (uint)size);
    ret = GetFileVersionInfo(s, 0, size, h);
    ret = VerQueryValue(
      h,
      "\\StringFileInfo\\040904b0\\ProductName",
      ref product,
      ref usize);
    LocalFree(h);
    MessageBox.Show(Marshal.PtrToStringUni(product));
  }

利用している API、クラスライブラリのメソッドは以下。一応、すべて Windows CE/Compact Framework でも対応している模様。Windows XP 上でしか動作確認してませんけどね。しかも、英語版オンリーだったり。日本語のバージョン情報が必要なときは、コードページと言語の指定を変更する必要があります。

  • GetFileVersionInfoSize()
  • LocalAlloc()
  • GetFileVersionInfo()
  • VerQueryValue()
  • LocalFree()
  • Marshal.PtrToStringUni()


2005-12-08

Profile

MyProfile のページをちょっと整理。振り返ってみると、結構いろいろやってるなぁと感慨深いものです。整理をしてみると、Web サイトの構成をいろいろ変えてみたくなったり、あれやこれや思いついてしまいます。時間がないので、大掛かりなことはできないですけど。


2005-12-05

December

やる気がめっきり減退中。上海がこんなに寒いところだとはいざ知らず。やっぱり、南国があってるのかと思うことしきり。寒くてもいいんです。お風呂には入れれば。お風呂でのんびり読書がしたいです。ふぅ。