Outil de ligne de commande pour vider la version de Windows DLL?
-
03-07-2019 - |
Question
J'ai besoin d'un outil de ligne de commande pour vider les informations de version de DLL Windows standard afin de pouvoir les traiter à l'aide d'un script bash (Cygwin).
En tant que développeur Java, je ne suis pas très habitué aux outils de développement Microsoft (même si je connais un peu Microsoft Visual Embedded C ++ 4.0 et Microsoft Visual Basic 6.0).
L'outil approprié semble être mt.exe , en tant que < a href = "https://stackoverflow.com/questions/420852/reading-an-applications-manifest-file"> indiqué sur l’objectif de consolidation . Cependant, la seule chance que j'ai trouvée pour obtenir cette petite application est de télécharger une image ISO de 1,29 Go du Kit de développement logiciel (SDK) Windows pour Windows Server 2008 et .NET Framework . Je ne peux pas croire que c'est la seule façon de le faire.
J'ai également trouvé une petite application sur Internet appelée PEView , mais elle en affiche trop. (et inutile dans mon cas) des informations et ce n'est pas une application en ligne de commande.
La norme objdump fournie dans Cygwin peut également afficher des informations sur les fichiers DLL, mais je peux ne voyez pas l’option de vider la version DLL. Notez que MajorImageVersion, MinorImageVersion et les autres champs vidés par cet outil (avec l'option -p) ne sont pas liés à la propre version de la DLL.
Des alternatives sur ce qu'il faut faire? Peut-être ai-je raté une option importante pour objdump? Est-ce que mt.exe est mon seul choix? Si tel est le cas, est-il possible de l'obtenir séparément du Kit de développement logiciel (SDK) Windows?
La solution
Vous pouvez également consulter le fichier filever.exe, qui peut être téléchargé dans le cadre du Ensemble des outils de support de Windows XP SP2 - seulement 4,7 Mo de téléchargement.
Autres conseils
Vous pouvez utiliser PowerShell pour obtenir les informations souhaitées.
(Get-Item C:\Path\To\MyFile.dll).VersionInfo
Par défaut, ProductVersion et FileVersion seront affichés. Mais la totalité du VERSIONINFO est disponible. C'est à dire. pour retourner les commentaires
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments
Utilisez Sigcheck Microsoft Sysinternals . Cet exemple affiche uniquement la version:
sigcheck -q -n foo.dll
Le fichier sigcheck.exe non compressé ne représente que 228 Ko.
Vous pouvez écrire un script VBScript pour obtenir les informations sur la version du fichier:
VersionInfo.vbs
set args = WScript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetFileVersion(args(0))
Wscript.Quit
Vous pouvez appeler cela à partir de la ligne de commande comme suit:
cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll
ou vous pouvez en construire un vous-même. Ouvrez VS, créez une nouvelle application console. Créez un projet simple sans support ATL ou MFC, laissez l'option stdafx cochée, mais ne cochez pas la case 'Projet vide' et appelez-la VersionInfo.
Vous obtiendrez un projet simple avec 2 fichiers: VersionInfo.cpp et VersionInfo.h
Ouvrez le fichier cpp et collez-le dans le fichier, puis compilez-le. Vous pourrez l'exécuter. Le premier argument est le nom de fichier complet. Il imprimera "Produit: 5.6.7.8 Fichier: 1.2.3.4" en fonction du bloc de ressources Version. S'il n'y a pas de ressource de version, il retournera -1, sinon 0.
Compile en un fichier binaire 8k à l'aide de la dll CRT, 60k avec tout ce qui est lié de manière statique (défini dans les options C ++, modifiez la page "Génération de code, les options d'exécution" en "/ MT")
.HTH.
PS. Si vous ne souhaitez pas utiliser Visual Studio, il compilera tout en utilisant un compilateur c ++ (doigts croisés), mais vous devrez certainement changer le # pragma - spécifiez simplement cette lib dans les paramètres de l'éditeur de liens, celle du pragma. juste un raccourci pour se connecter automatiquement avec cette bibliothèque.
// 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
Les outils listdlls de Systernals peuvent faire le travail: http: // technet. microsoft.com/en-us/sysinternals/bb896656.aspx
listdlls -v -d mylib.dll
Cette fonction renvoie les détails du fichier Windows ntfs pour tout fichier utilisant Cygwin bash (valeur réelle de r-click-properties-info) au terme
.Transmettez le chemin des fichiers à finfo (), il peut s’agir du chemin unix, du chemin dos, relatif ou absolu. Le fichier est converti en un chemin nix absolu, puis vérifié pour voir s’il s’agit bien d’un fichier ordinaire / existant. Ensuite converti en un chemin Windows absolu et envoyé à "wmic". Alors magique, vous avez les détails de fichiers Windows directement dans le terminal. Utilisations: cygwin, cygpath, sed et awk. Nécessite Windows WMI " wmic.exe " être opérationnel. La sortie est corrigée pour facile ...
$ 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" }'
}
En utilisant Powershell, il est possible d’obtenir uniquement la chaîne Version, c’est-à-dire 2.3.4 à partir de n'importe quelle dll ou exe à l’aide de la commande suivante
(Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion
Testé sous Windows 10
Il existe une application en ligne de commande appelée "ShowVer " sur CodeProject:
Programme d'affichage VERSIONINFO en ligne de commande de ShowVer.exe
Comme d'habitude, l'application est fournie avec un exe et le code source (VisualC ++ 6).
Out affiche toutes les métadonnées disponibles:
Sur un système allemand Win7, le résultat de user32.dll est le suivant:
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
et dans un sens avec 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*"
exemple de sortie (il a une version chaîne qui est un petit ajout à la méthode 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
et un de plus Utilisation de shell.application et du lot hybride \ jscript.Voici 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();
utilisé contre 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