Windows DLLのバージョンをダンプするコマンドラインツール?
-
03-07-2019 - |
質問
bash スクリプト (Cygwin) で処理できるように、標準の Windows DLL バージョン情報をダンプするコマンド ライン ツールが必要です。
Java 開発者として、私は Microsoft 開発ツールにはあまり慣れていません (ただし、Microsoft Visual Embedded C++ 4.0 と Microsoft Visual Basic 6.0 については少し経験があります)。
適切なツールは次のようです mt.exe, 、 として SOに記載されている. 。ただし、この小さなアプリケーションを入手できる唯一のチャンスは、次の 1.29 GB ISO をダウンロードすることです。 Windows Server 2008 および .NET Framework 用の Windows SDK. 。これが唯一の方法だなんて信じられません。
インターネット上で次のような小さなアプリケーションも見つけました。 PEビュー, しかし、表示される情報が多すぎます(私の場合は役に立たず、コマンドラインアプリケーションではありません)。
標準 オブジェクトダンプ Cygwin 内にバンドルされている DLL ファイルに関する情報をダンプすることもできますが、DLL バージョンをダンプするオプションが表示されません。MajorImageVersion、MinorImageVersion、およびこのツール (-p オプションを使用) によってダンプされるその他のフィールドは、独自の DLL バージョンに関連しないことに注意してください。
何か代替策はありますか?もしかしたら、重要な objdump オプションを見逃してしまったのでしょうか?mt.exe が唯一の選択肢ですか?この場合、Windows SDKとは別に入手することは可能でしょうか?
解決
filever.exe も参照できます。これは、 Windows XP SP2 サポート ツール パッケージ - ダウンロード量はわずか 4.7MB です。
他のヒント
PowerShell を使用して、必要な情報を取得できます。
(Get-Item C:\Path\To\MyFile.dll).VersionInfo
デフォルトでは、これによりProductVersionとfileversionが表示されますが、 バージョン情報 利用可能です。つまり、コメントを返す
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments
使用 Microsoft Sysinternals Sigcheck。このサンプルはバージョンのみを出力します。
sigcheck -q -n foo.dll
解凍した sigcheck.exe はわずか 228 KB です。
VBScript スクリプトを記述して、ファイルのバージョン情報を取得できます。
バージョン情報.vbs
set args = WScript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetFileVersion(args(0))
Wscript.Quit
次のようにコマンドラインからこれを呼び出すことができます。
cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll
または自分で構築することもできます。VS を開き、新しいコンソール アプリケーションを作成します。ATL または MFC サポートのない単純なプロジェクトを作成し、stdafx オプションをオンのままにしておきますが、「空のプロジェクト」にはチェックを入れず、それを VersionInfo と呼びます。
2 つのファイルを含む単純なプロジェクトが得られます。VersionInfo.cpp と VersionInfo.h
cpp ファイルを開き、次の内容を貼り付けてコンパイルします。実行できます。最初の引数は完全なファイル名で、出力されます。 "製品:5.6.7.8 ファイル:1.2.3.4インチ Version リソース ブロックに基づきます。バージョン リソースがない場合は -1 を返し、それ以外の場合は 0 を返します。
dll CRT を使用して 8k バイナリにコンパイルし、すべてを静的にリンクして 60k にコンパイルします (C++ オプションで設定し、「コード生成ページ、ランタイム オプション」を「/MT」に変更します)。
HTH。
PS.Visual Studio を使用したくない場合でも、任意の C++ コンパイラーを使用してコンパイルできますが、ほぼ確実に #pragma を変更する必要があります。代わりに、リンカー設定でその lib を指定するだけで、プラグマのそのライブラリに自動的にリンクするための単なる省略表現です。
// VersionInfo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#pragma comment(lib, "version.lib")
int _tmain(int argc, _TCHAR* argv[])
{
DWORD handle = 0;
DWORD size = GetFileVersionInfoSize(argv[1], &handle);
BYTE* versionInfo = new BYTE[size];
if (!GetFileVersionInfo(argv[1], handle, size, versionInfo))
{
delete[] versionInfo;
return -1;
}
// we have version information
UINT len = 0;
VS_FIXEDFILEINFO* vsfi = NULL;
VerQueryValue(versionInfo, L"\\", (void**)&vsfi, &len);
WORD fVersion[4], pVersion[4];
fVersion[0] = HIWORD(vsfi->dwFileVersionMS);
fVersion[1] = LOWORD(vsfi->dwFileVersionMS);
fVersion[2] = HIWORD(vsfi->dwFileVersionLS);
fVersion[3] = LOWORD(vsfi->dwFileVersionLS);
pVersion[0] = HIWORD(vsfi->dwProductVersionMS);
pVersion[1] = LOWORD(vsfi->dwProductVersionMS);
pVersion[2] = HIWORD(vsfi->dwProductVersionLS);
pVersion[3] = LOWORD(vsfi->dwProductVersionLS);
printf("Product: %d.%d.%d.%d File: %d.%d.%d.%d\n",
pVersion[0], pVersion[1],
pVersion[2], pVersion[3],
fVersion[0], fVersion[1],
fVersion[2], fVersion[3]);
delete[] versionInfo;
return 0;
}
C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version
Version
6.1.7601.18229
Systernals の listdlls ツールがその仕事を行う可能性があります。 http://technet.microsoft.com/en-us/sysinternals/bb896656.aspx
listdlls -v -d mylib.dll
この関数は、Cygwin bash (実際の r-click-properties-info) を使用して、あらゆるファイルの ntfs Windows ファイルの詳細を返します。
ファイル パスを finfo() に渡します。UNIX パス、DOS パス、相対パスまたは絶対パスを指定できます。ファイルは絶対 nix パスに変換され、実際に通常の/既存のファイルであるかどうかがチェックされます。次に、絶対 Windows パスに変換され、「wmic」に送信されます。そうすれば、魔法のように、ターミナルに Windows ファイルの詳細が表示されます。用途:cygwin、cygpath、sed、および awk。動作するには、Windows WMI「wmic.exe」が必要です。出力は簡単に修正されています...
$ finfo notepad.exe
$ finfo "C:\windows\system32\notepad.exe"
$ finfo /cygdrive/c/Windows/System32/notepad.exe
$ finfo "/cygdrive/c/Program Files/notepad.exe"
$ finfo ../notepad.exe
finfo() {
[[ -e "$(cygpath -wa "$@")" ]] || { echo "bad-file"; return 1; }
echo "$(wmic datafile where name=\""$(echo "$(cygpath -wa "$@")" | sed 's/\\/\\\\/g')"\" get /value)" |\
sed 's/\r//g;s/^M$//;/^$/d' | awk -F"=" '{print $1"=""\033[1m"$2"\033[0m" }'
}
Powershell を使用すると、バージョン文字列だけを取得することができます。2.3.4 次のコマンドを使用して任意の dll または exe から実行します。
(Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion
Windows 10でテスト済み
CodeProject には「ShowVer」というコマンド ライン アプリケーションがあります。
ShowVer.exe コマンドライン VERSIONINFO 表示プログラム
いつものように、アプリケーションには exe とソース コード (VisualC++ 6) が付属しています。
Out は利用可能なすべてのメタデータを出力します。
ドイツの Win7 システムでは、user32.dll の出力は次のようになります。
VERSIONINFO for file "C:\Windows\system32\user32.dll": (type:0)
Signature: feef04bd
StrucVersion: 1.0
FileVersion: 6.1.7601.17514
ProductVersion: 6.1.7601.17514
FileFlagsMask: 0x3f
FileFlags: 0
FileOS: VOS_NT_WINDOWS32
FileType: VFT_DLL
FileDate: 0.0
LangID: 040704B0
CompanyName : Microsoft Corporation
FileDescription : Multi-User Windows USER API Client DLL
FileVersion : 6.1.7601.17514 (win7sp1_rtm.101119-1850)
InternalName : user32
LegalCopyright : ® Microsoft Corporation. Alle Rechte vorbehalten.
OriginalFilename : user32
ProductName : Betriebssystem Microsoft« Windows«
ProductVersion : 6.1.7601.17514
Translation: 040704b0
そして一方通行で makecab
:
; @echo off
;;goto :end_help
;;setlocal DsiableDelayedExpansion
;;;
;;;
;;; fileinf /l list of full file paths separated with ;
;;; fileinf /f text file with a list of files to be processed ( one on each line )
;;; fileinf /? prints the help
;;;
;;:end_help
; REM Creating a Newline variable (the two blank lines are required!)
; set NLM=^
; set NL=^^^%NLM%%NLM%^%NLM%%NLM%
; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; setlocal enableDelayedExpansion
; if "%~1" equ "/l" (
; set "_files=%~2"
; echo !_files:;=%NL%!>"%TEMP%\file.paths"
; set _process_file="%TEMP%\file.paths"
; goto :get_info
; )
; if "%~1" equ "/f" if exist "%~2" (
; set _process_file="%~2"
; goto :get_info
; )
; echo incorect parameters & exit /b 1
; :get_info
; set "file_info="
; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0" /f %_process_file% /v0>nul
; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do (
; set "file_info=%%f"
; echo !file_info:,=%nl%!
; )
; endlocal
;endlocal
; del /q /f %TEMP%\file.inf 2>nul
; del /q /f %TEMP%\file.path 2>nul
; exit /b 0
.set DoNotCopyFiles=on
.set DestinationDir=;
.set RptFileName=nul
.set InfFooter=;
.set InfHeader=;
.Set ChecksumWidth=8
.Set InfDiskLineFormat=;
.Set Cabinet=off
.Set Compress=off
.Set GenerateInf=ON
.Set InfDiskHeader=;
.Set InfFileHeader=;
.set InfCabinetHeader=;
.Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*"
出力例 (wmic メソッドに少し追加した文字列バージョンがあります :) ):
c:> fileinfo.bat /l C:\install.exe
file:install.exe
date:11/07/07
size:562688
csum:380ef239
time:07:03:18a
vern:9.0.21022.8
vers:9.0.21022.8 built by: RTM
lang:1033
そしてもう 1 つ シェル.アプリケーション およびハイブリッド バッチ\jscript。ここにあります tooptipInfo.bat :
@if (@X)==(@Y) @end /* JScript comment
@echo off
rem :: the first argument is the script name as it will be used for proper help message
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%
@if (@X)==(@Y) @end JScript comment */
//////
FSOObj = new ActiveXObject("Scripting.FileSystemObject");
var ARGS = WScript.Arguments;
if (ARGS.Length < 1 ) {
WScript.Echo("No file passed");
WScript.Quit(1);
}
var filename=ARGS.Item(0);
var objShell=new ActiveXObject("Shell.Application");
/////
//fso
ExistsItem = function (path) {
return FSOObj.FolderExists(path)||FSOObj.FileExists(path);
}
getFullPath = function (path) {
return FSOObj.GetAbsolutePathName(path);
}
//
//paths
getParent = function(path){
var splitted=path.split("\\");
var result="";
for (var s=0;s<splitted.length-1;s++){
if (s==0) {
result=splitted[s];
} else {
result=result+"\\"+splitted[s];
}
}
return result;
}
getName = function(path){
var splitted=path.split("\\");
return splitted[splitted.length-1];
}
//
function main(){
if (!ExistsItem(filename)) {
WScript.Echo(filename + " does not exist");
WScript.Quit(2);
}
var fullFilename=getFullPath(filename);
var namespace=getParent(fullFilename);
var name=getName(fullFilename);
var objFolder=objShell.NameSpace(namespace);
var objItem=objFolder.ParseName(name);
//https://msdn.microsoft.com/en-us/library/windows/desktop/bb787870(v=vs.85).aspx
WScript.Echo(fullFilename + " : ");
WScript.Echo(objFolder.GetDetailsOf(objItem,-1));
}
main();
cmd.exe に対して使用されます:
C:\Windows\System32\cmd.exe :
File description: Windows Command Processor
Company: Microsoft Corporation
File version: 6.3.9600.16384
Date created: ?22-?Aug-?13 ??13:03
Size: 347 KB