miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

VC++ ファイル群の GUID 置き換え

また間があきましたが 前回 の続き。

これに従ってアイコンオーバーレイを実現しようと思ったのですが、この説明は「ATL プロジェクトを作成してウィザードに従いましょう」というもので。Express Edition では ATL がサポートされていないので、この方法でプロジェクトを作成することはできません。

このソースをそのまま流用することもできるんですが、そうすると同じくこのソースを流用したソフトがあった場合に GUID が被って予期しない動作をしてしまいそうです。そこで、カレントディレクトリ配下の全ファイルについて、GUID らしきものがあれば新規発行した GUID に置き換える Ruby スクリプトを書いてみました。

置換対象

Visual Studio コマンド プロンプト(2010) から起動できる guidgen.exe では、以下の 6 種類の形式で GUID を生成できるようです。

// {4080DB5E-3453-4C40-8FF6-13FE3867F51F}
IMPLEMENT_OLECREATE(<<class>>, <<external_name>>, 
0x4080db5e, 0x3453, 0x4c40, 0x8f, 0xf6, 0x13, 0xfe, 0x38, 0x67, 0xf5, 0x1f);

// {4080DB5E-3453-4C40-8FF6-13FE3867F51F}
DEFINE_GUID(<<name>>, 
0x4080db5e, 0x3453, 0x4c40, 0x8f, 0xf6, 0x13, 0xfe, 0x38, 0x67, 0xf5, 0x1f);

// {4080DB5E-3453-4C40-8FF6-13FE3867F51F}
static const GUID <<name>> = 
{ 0x4080db5e, 0x3453, 0x4c40, { 0x8f, 0xf6, 0x13, 0xfe, 0x38, 0x67, 0xf5, 0x1f } };

{4080DB5E-3453-4C40-8FF6-13FE3867F51F}

[Guid("4080DB5E-3453-4C40-8FF6-13FE3867F51F")]

<Guid("4080DB5E-3453-4C40-8FF6-13FE3867F51F")>

とりあえずこの 6 種類の形式は置換できるような造りにしています。

完成品

例によって Gist に置いています。

注意点等
  • 置換ファイルのバックアップ等は行っていませんので、バックアップはあらかじめ取得しておいてください。(というか Git とかで管理することをオススメします。)
  • Symbol#to_proc を使っているので、ruby 1.9.x か 1.8.7 でないと動かないと思います。
  • 特殊な意味を持つ GUID を置き換えたくない場合は、10 行目くらいにある guid_shouldnot_replace に適宜追加してください。
使い方
gem install uuidtools

してインストールしてください。

ruby replace_giud.rb

のようにして起動してください。置換前、置換後の GUID が出力されます。(ちょっと長いですけどログを貼っておきます。)

dlldata.c
my.ico
MyOverlayIcon.cpp
MyOverlayIcon.h
MyOverlayIcon.rgs
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
  adf1fa2a-6eaa-4a97-a55f-3c8b92843ef5 -> c85c160b-472d-4b56-8d64-297a9bf231d8
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
OverlayIcon.cpp
  fa8edcdd-efa2-477b-b00a-7f28f02cd37e -> 3feda8ec-3031-4157-b976-fb2521bb2a4e
OverlayIcon.def
OverlayIcon.h
  7bca6879-a9f8-47de-ae05-f5ce7ea3a474 -> cd76dc2c-7550-46a7-bfa7-c5f3253896d3
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
OverlayIcon.idl
  7bca6879-a9f8-47de-ae05-f5ce7ea3a474 -> cd76dc2c-7550-46a7-bfa7-c5f3253896d3
  adf1fa2a-6eaa-4a97-a55f-3c8b92843ef5 -> c85c160b-472d-4b56-8d64-297a9bf231d8
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
OverlayIcon.rc
OverlayIcon.rgs
OverlayIcon.sln
  8bc9ceb8-8b4a-11d0-8d11-00a0c91bc942 -> 654115d3-0a2e-4d6c-bbad-0b1f56b03b7b
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
  8bc9ceb8-8b4a-11d0-8d11-00a0c91bc942 -> 654115d3-0a2e-4d6c-bbad-0b1f56b03b7b
  eb535a1b-6fd7-4b9f-bd67-1015d94d333e -> 0247bd6b-6136-446f-a470-419d105414c2
  eb535a1b-6fd7-4b9f-bd67-1015d94d333e -> 0247bd6b-6136-446f-a470-419d105414c2
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
  eb535a1b-6fd7-4b9f-bd67-1015d94d333e -> 0247bd6b-6136-446f-a470-419d105414c2
  eb535a1b-6fd7-4b9f-bd67-1015d94d333e -> 0247bd6b-6136-446f-a470-419d105414c2
OverlayIcon.vcproj
  99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
OverlayIconps.def
OverlayIconPS.vcproj
  eb535a1b-6fd7-4b9f-bd67-1015d94d333e -> 0247bd6b-6136-446f-a470-419d105414c2
OverlayIcon_i.c
  7bca6879-a9f8-47de-ae05-f5ce7ea3a474 -> cd76dc2c-7550-46a7-bfa7-c5f3253896d3
  adf1fa2a-6eaa-4a97-a55f-3c8b92843ef5 -> c85c160b-472d-4b56-8d64-297a9bf231d8
  81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4
OverlayIcon_p.c
  8a885d04-1ceb-11c9-9fe8-08002b104860 -> (skipped - _RpcTransferSyntax)
  00000000-0000-0000-c000-000000000046 -> (skipped - IUnknown, ver. 0.0,)
  00020400-0000-0000-c000-000000000046 -> (skipped - IDispatch, ver. 0.0)
  7bca6879-a9f8-47de-ae05-f5ce7ea3a474 -> cd76dc2c-7550-46a7-bfa7-c5f3253896d3
ReadMe.txt
resource.h
stdafx.cpp
stdafx.h

=== Summary ===
7bca6879-a9f8-47de-ae05-f5ce7ea3a474 -> cd76dc2c-7550-46a7-bfa7-c5f3253896d3
8bc9ceb8-8b4a-11d0-8d11-00a0c91bc942 -> 654115d3-0a2e-4d6c-bbad-0b1f56b03b7b
fa8edcdd-efa2-477b-b00a-7f28f02cd37e -> 3feda8ec-3031-4157-b976-fb2521bb2a4e
99bb894f-15bb-49c0-a179-a07ce3054c38 -> 3d7583db-853c-4c4d-8636-ae37cee59321
adf1fa2a-6eaa-4a97-a55f-3c8b92843ef5 -> c85c160b-472d-4b56-8d64-297a9bf231d8
eb535a1b-6fd7-4b9f-bd67-1015d94d333e -> 0247bd6b-6136-446f-a470-419d105414c2
81539fe6-33c7-4ce7-90c7-1c7b8f2f2d40 -> fa8a9bc5-1c0c-4a5e-992e-5f9235025fa4

ちゃんとした(?)方法

たぶん正攻法だとこんな感じでやるんだと思います。

  1. Visual Studio コマンド プロンプト(2010) から guidgen.exe を起動して GUID 発行
  2. OverlayIcon.idl 中の GUID を新規発行したもので書き換え
  3. Visual Studio コマンド プロンプトを起動して、
midl OverlayIcon.idl

を実行。そうすると .c や .h ファイル中の GUID がそれらしく置き換えられます。

ただ、バージョンの違い等があるので GUID 以外の部分も置き換えられてしまいます。

(蛇足)PowerShell でやりたかったんだけど・・・

似たようなツールを捜すと、C#PowerShell 版が以下のページで紹介されていました。

ただ、同じ GIUD が出現した場合にも別々の文字列に置き換えてしまう+対応フォーマットが少ないようなので、今回新たにスクリプトを書いたのでした。

PowerShell を使えば

$guid = [guid]::NewGuid()

で GUID を生成できるし、Ruby

re_define_guid = Regexp.new(
  '0x([0-9a-f]{8})' + ',\s*0x([0-9a-f]{4})' * 2 + ',\s*0x([0-9a-f]{2})' * 8,
  Regexp::IGNORECASE
)

とやって文字列で組み立てていた正規表現も、.NET の Capture オブジェクトが使える(キャプチャの過程を全部拾える)から

$re_define_guid = New-Object Text.RegularExpressions.Regex(
    "0x([0-9a-f]{8})(?:,\s*0x([0-9a-f]{4})){2}(?:,\s*0x([0-9a-f]{2})){8}"
)

みたいに書けたはずだし、結構いい具合に書けたような気もするんですが、今は時間がないので Ruby でやっつけたのでした。余裕ができたら PowerShell 版にチャレンジしたいなぁ。