ファイル情報の取得

リソースにて管理されている、ファイルバージョンとファイル名を取得する方法を調査メモ

 GetFileVersionInfo
 VerQueryValue

を利用したらできるらしいが、今のところうまいこといってない。
うーん、関数の使い方を間違えてるんだろうなぁ。。。

■サンプル情報
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/version.html#PrintFileVersion_path
MSDN
GetFileVersionInfoSize
 http://msdn.microsoft.com/ja-jp/library/cc364632.aspx
GetFileVersionInfo
 http://msdn.microsoft.com/ja-jp/library/cc364631.aspx
VerQueryValue
 http://msdn.microsoft.com/ja-jp/library/cc364858.aspx

MACアドレスの取得 2

昨日に引き続き、本日も調査を兼ねて取り掛かる。

Netbiosを使用した方法で実装することにした。

まず、Netbiosを使用するにあたり、以下のヘッダーとlibファイルを取り込む必要がある。

#include "Nb30.h"
#pragma comment( lib, "Netapi32.lib" )

あとは、Netbios()を使用し、NICカードの枚数を取得し、
その枚数分、MACアドレスの取得を試みる。
※細かいところは…とりあえずおいとく(汗)
※ソースのベースは他の方から引用させてもらってます('_';

■以下、サンプルソース
CString変数strMacBuffを"00-11-22-33-44-55"と表示できるように文字列操作を行っている。

struct ASTAT
{
/* ADAPTER_STATUS: http://msdn.microsoft.com/en-us/library/bb870890(v=vs.85).aspx */
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff[30];
};

int i;
NCB sNcb;
UCHAR uRetCode;
LANA_ENUM lenum;
ASTAT Adapter;
CString strMacBuff = _T(""); // MACアドレス格納
char szBuff[MAX_PATH];

//初期化

ZeroMemory( &szBuff, sizeof(szBuff) );

// NIC数の取得

ZeroMemory( &sNcb, sizeof(sNcb) );

sNcb.ncb_command = NCBENUM;
sNcb.ncb_buffer = (UCHAR*)&lenum;
sNcb.ncb_length = sizeof(lenum);

uRetCode = Netbios( &sNcb );
if( 0 != uRetCode ){
// MessageBox(_T("取得失敗"),0,0);
return;
}

for( i = 0; i < lenum.length; i++){ // NIC数分繰り返す
//NICのリセット
::ZeroMemory( &sNcb, sizeof(sNcb) );
sNcb.ncb_command = NCBRESET; // NCBRESETコマンド
sNcb.ncb_lana_num = lenum.lana[i];
uRetCode = Netbios( &sNcb ); // Netbios命令を実行
if( 0 != uRetCode ){
// MessageBox(_T("リセット失敗"),0,0);
return;
}

// MACアドレスを取得
::ZeroMemory( &sNcb, sizeof(sNcb) );
sNcb.ncb_command = NCBASTAT; // NCBASTATコマンド
sNcb.ncb_lana_num = lenum.lana[i];
strcpy( (char*)(sNcb.ncb_callname), "* " );
sNcb.ncb_buffer = (UCHAR*)&Adapter;
sNcb.ncb_length = sizeof(Adapter);

uRetCode = Netbios(&sNcb);
if( 0 != uRetCode ){
// MessageBox(_T("MACアドレス取得失敗"),0,0);
return;
}

if( 0 == uRetCode ){
sprintf(szBuff, "%02X-%02X-%02X-%02X-%02X-%02X"
, Adapter.adapt.adapter_address[0]
, Adapter.adapt.adapter_address[1]
, Adapter.adapt.adapter_address[2]
, Adapter.adapt.adapter_address[3]
, Adapter.adapt.adapter_address[4]
, Adapter.adapt.adapter_address[5]);

// **-**-**-**-**-**へ形式を変えたMACアドレスを送信用変数へ格納
strMacBuff = szBuff;
}
}


以上、MACアドレスの取得方法のメモ。

MACアドレスの取得

VC++を使用してMACアドレスを取得できないか、という問い合わせが入った。

とりあえず、以下はメモ

・Platform SDK(Internet Protocol Helper)を使用して実装する方法
 【参考リンク】
 http://www.dinop.com/vc/getmac_iphlpapi2.html
 http://www.geekpage.jp/programming/ruby-network/iphlpapi-getiftable.php

DOSコマンドを実行(ipconfig?)し、そこからMACアドレスを抽出

Google先生からはいろんな検索結果がでてきたので、
後に使えそうな材料をピックアップする。


以上、メモ書き。

UAC制御を起動するようにする

WindowsXP上で作成したアプリがWindows 7上で動かない・・・。
どうやら、レジストリへアクセスしている処理が原因になっているらしく、
UAC制御がいたずらしているらしい。

VSのデフォルトの設定では、マニフェストファイルの設定が以下のようになっていた。

どうやらUAC実行レベルの設定がまずいらしい。
この設定を、"requireAdministrator"にすることで、
Vista以降に実装されたUAC制御を起動し、アプリにレジストリへのアクセス権限を与えてくれる模様。


■/MANIFESTUAC (UAC 情報をマニフェストに組み込む)
http://msdn.microsoft.com/ja-jp/library/bb384691.aspx

windowsのプロダクトキーを取得する

WindowsXP以降のプロダクトキーを取得する方法のメモ

以下の作法で、レジストリキーの読み取りを行う。

レジストリキーのオープン処理関数をコール
 RegCreateKeyEx(...)関数を実施

レジストリキーの読み込み処理関数をコール
 RegQueryValueEx(...)

レジストリキーのクローズ処理関数をコール
 RegCloseKey(...)

以下、サンプルコード=======

CString strPathName = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
CString strValueName = _T("DigitalProductId");

HKEY hKey; // キーハンドル
DWORD dwDisposition; // 処理結果を受け取る
LONG lResult; // 関数の戻り値を格納する
DWORD dwType; // 値の種類を受け取る
DWORD dwSize; // 値のサイズを受け取る
BYTE byPdky[MAX_PATH]; // プロダクトキーを受け取る
CString strPdky = _T("");
CString strTmpPdky = _T("");

dwType = REG_BINARY;

// 初期化
memset( &byPdky, '\0', MAX_PATH );

// レジストリオープン処理
lResult = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, strPathName, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
if( ERROR_SUCCESS != lResult ){
MessageBox(_T("RegCreateKeyEx() Error"), MB_OK, MB_ICONERROR );
return;
}

// レジストリ読み込み処理
lResult = ::RegQueryValueEx( hKey, strValueName, NULL, &dwType, NULL, &dwSize );
lResult = ::RegQueryValueEx( hKey, strValueName, NULL, &dwType, byPdky, &dwSize );
if( ERROR_SUCCESS != lResult ){
MessageBox(_T("RegQueryValue() Error"), MB_OK, MB_ICONERROR );
return;
}

// レジストリクローズ処理
::RegCloseKey( hKey );


ただし、WindowsXP以降はプロダクトキーが記録されているキー名DigitalProductIdは、
REG_BINARYで暗号化?されている。
VC++ではどうやるか考え中。
VC++以外の方法は何個かみつけてるんだが…。