C++ で GUIDを生成

(1/1)
C++でGUIDを生成
WiX によるWindowsインストーラー作成」で述べたが、インストーラーを作成するには、コンポーネントごとに GUID(Globally Unique Identifier)を求められる。
そこで今回は、C++を使ってWindows APIを呼び出し、1つまたは複数の GUID を生成するプログラムを作成する。生成した GUID をクリップボードにコピーしたり、テキストファイルに保存できるようにする。

(2022年7月16日)生成数,チェックの状態,ウィンドウ位置を保存.CUI版を追加,ライブラリを更新.DLLを不要に(静的リンクに変更)

目次

サンプル・プログラム

圧縮ファイルの内容
newguid.msiインストーラ
bin/newguid.exe実行プログラム本体
bin/etc/help.chmヘルプ・ファイル
sour/newguid.cppソース・プログラム
sour/resource.hリソース・ヘッダ
sour/resource.rcリソース・ファイル
sour/application.icoアプリケーション・アイコン
sour/makefileGUI版ビルド
sour/makefile_cmdCUI版ビルド

GUIDとは

世界中で重複することがなく、ユニークであることが保証された128ビットのランダムな数値のことを UUID(Universally Unique IDentifier)と呼び、OSF(Open Software Foundation)のDCE(Distributed Computing Environment)仕様によって128ビットの2進数値として決まった。
実際に UUID を生成するには、作成するPCのMACアドレスなどを取り込むなどしている。

UUID を16進数32桁の文字列表記にしたものが GUID である。たとえば AAA0452F-17B5-43AB-BB7E-52F60C1C2412 のように表記する。
Windowsシステムでは、レジストリ・エントリなど、さまざまな識別に GUID が用いられており、Windows API(OLE32)を使って生成することができる。
今回のプログラムでは、このAPIをコールして GUID を生成することを目指す。

使用ライブラリ

今回は、オープンソースのライブラリ Boost C++ライブラリを使用する。導入方法等については、「C++ 開発環境の準備」をご覧いただきたい。

リソースの準備

Eclipse を起動し、新規プロジェクト newguid を用意する。
ResEdit を起動し、resource.rc を用意する。
Eclipse に戻り、ソース・プログラム "newguid.cpp" を追加する。
今回は GDI+ を使用する関係で、リンカー・フラグを -mwindows -static -lstdc++ -lgcc -lwinpthread "C:\Windows\System32\ole32.dll" に設定する。

MSYS2 コマンドラインからビルドするのであれば、"makefile" と "makefile_cmd" を利用してほしい。

解説:ヘッダファイル等

0011: // 初期化処理 ======================================================
0012: #include <iostream>
0013: #include <stdio.h>
0014: #include <stdlib.h>
0015: #include <tchar.h>
0016: #include <sstream>
0017: #include <string>
0018: #include <fstream>
0019: #include <windows.h>
0020: #include <commctrl.h>
0021: #include <shlobj.h>
0022: #include <richedit.h>
0023: #include <boost/format.hpp>
0024: #include <boost/program_options.hpp>
0025: #include <boost/property_tree/xml_parser.hpp>
0026: #include "resource.h"
0027: 
0028: using namespace std;
0029: using namespace boost;
0030: using namespace boost::program_options;
0031: using namespace boost::property_tree;
0032: 
0033: #define APPNAME        "newguid"     //アプリケーション名(GUI版)
0034: #define APPNAMEJP  "GUID生成"      //アプリケーション名(日本語)
0035: #define APPCMD     "nguid"           //アプリケーション名(CUI版)
0036: #define APPVERSION "1.3"         //バージョン
0037: #define APPYEAR        "2020-2022"       //作成年
0038: #define REFERENCE  "https://www.pahoo.org/e-soul/webtech/cpp01/cpp01-10-01.shtm" // 参考サイト
0039: 
0040: //char*バッファサイズ
0041: #define SIZE_BUFF      512
0042: 
0043: //標準フォント
0044: #define FONT_FACE      "MS UI Gothic"
0045: 
0046: //現在のインターフェイス
0047: HINSTANCE hInst;
0048: 
0049: //アプリケーション・ウィンドウ
0050: HWND hParent;
0051: 
0052: //アプリケーション・ウィンドウ位置
0053: unsigned hParent_XhParent_Y;
0054: 
0055: //エラー・メッセージ格納用
0056: string ErrorMessage;
0057: 
0058: //ヘルプ・ファイル
0059: #define HELPFILE   ".\\etc\\help.chm"
0060: 
0061: //デフォルト保存ファイル名
0062: #define SAVEFILE   "newguid.txt"
0063: 
0064: //オプション
0065: #define OPTION_ADD_BRACE   'b'       //{...} 追加
0066: #define OPTION_TRIM_HYPHEN 't'       //ハイフン削除
0067: 
0068: //オプションの初期値
0069: #define OPTION_INIT            ""
0070: 
0071: //生成するGUIDの最小数と最大数
0072: #define MIN_GUID   1
0073: #define MAX_GUID   10

各種定数は、自由に変更できる。

解説:GUIDを生成

0170: /**
0171:  * GUIDを1つ生成する
0172:  * @param   int fmt 生成文字列の書式ID
0173:  *                      0:通常, 1:ハイフン無し, 2:ブレース有り,ハイフン有り
0174:  *                      3:ブレース有り,ハイフン無し
0175:  * @return  string GUID/NULL:生成失敗
0176: */
0177: string newGUID(int fmt) {
0178:     GUID guid;
0179:     static char buff[SIZE_BUFF + 1];
0180:     //生成文字列の書式
0181:     const char *format[] = {
0182:         "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
0183:         "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
0184:         "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
0185:         "{%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X}"
0186:     };
0187:     if ((fmt < 0) || (fmt > (int)sizeof(format))) {
0188:         ErrorMessage = "生成文字列の書式が不正";
0189:         return "";
0190:     }
0191: 
0192:     //GUIDの生成(Windows API利用)
0193:     if (S_OK != ::CoCreateGuid(&guid)) {
0194:         ErrorMessage = "GUID生成に失敗";
0195:         return "";
0196:     } else {
0197:         snprintf(buffSIZE_BUFFformat[fmt], guid.Data1guid.Data2guid.Data3guid.Data4[0],guid.Data4[1],guid.Data4[2],guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
0198:     }
0199: 
0200:     return (string)buff;
0201: }

Windows API の CoCreateGuid を呼び出し、GUIDを1つ生成する。

その他の関数、ヘルプファイルやインストーラー作成方法については、これまでの連載で説明してきたとおりである。

参考サイト

(この項おわり)
header