尊敬されているWindowsBITSサービスのオープンソース.NETラッパー実装(SharpBITS)は、 Win7x64での基になるBITSバージョンの識別に失敗します。
失敗するソースコードは次のとおりです。NativeMethodsは、.NETメソッドによってラップされ、DllImport属性を介して装飾されたネイティブWin32呼び出しです。
private static BitsVersion GetBitsVersion()
{
try
{
string fileName = Path.Combine(
System.Environment.SystemDirectory, "qmgr.dll");
int handle = 0;
int size = NativeMethods.GetFileVersionInfoSize(fileName,
out handle);
if (size == 0) return BitsVersion.Bits0_0;
byte[] buffer = new byte[size];
if (!NativeMethods.GetFileVersionInfo(fileName,
handle,
size,
buffer))
{
return BitsVersion.Bits0_0;
}
IntPtr subBlock = IntPtr.Zero;
uint len = 0;
if (!NativeMethods.VerQueryValue(buffer,
@"\VarFileInfo\Translation",
out subBlock,
out len))
{
return BitsVersion.Bits0_0;
}
int block1 = Marshal.ReadInt16(subBlock);
int block2 = Marshal.ReadInt16((IntPtr)((int)subBlock + 2 ));
string spv = string.Format(
@"\StringFileInfo\{0:X4}{1:X4}\ProductVersion",
block1,
block2);
string versionInfo;
if (!NativeMethods.VerQueryValue(buffer,
spv,
out versionInfo,
out len))
{
return BitsVersion.Bits0_0;
}
...
実装は、MSDNの指示に従って文字で行われます。それでも2回目のVerQueryValue(...)呼び出し中に、アプリケーションはクラッシュし、ためらうことなくデバッグセッションを強制終了します。クラッシュ直前のもう少しデバッグ情報:
- spv => "\ StringFileInfo \ 040904B0 \ ProductVersion"
- buffer =>byte[1900]-バイナリデータでいっぱい
- block1 => 1033
- block2 => 1200
ターゲットの「C:\ Windows \ System32 \ qmgr.dll」ファイル(BITSの実装)をWindows経由で調べました。製品バージョンは7.5.7600.16385であると書かれています。クラッシュする代わりに、この値はverionInfo文字列で返される必要があります。何かアドバイス?