ferramenta de linha de comando para despejo versão Windows DLL?
-
03-07-2019 - |
Pergunta
Eu preciso de uma ferramenta de linha de comando para despejar padrão do Windows DLL informação de versão para que eu possa processá-lo por meio de um script bash (Cygwin).
Como um desenvolvedor Java que eu não sou muito usado para ferramentas de desenvolvimento da Microsoft (embora eu tenho um pouco de experiência com Microsoft Visual C ++ incorporado 4.0 e Microsoft Visual Basic 6.0).
A ferramenta apropriada parece ser Mt.exe , como < a href = "https://stackoverflow.com/questions/420852/reading-an-applications-manifest-file"> declarado no SO . No entanto, a única chance que eu encontrei para obter este pequeno aplicativo é baixar um 1,29 GB ISO do Windows SDK para Windows Server 2008 e .NET Framework . Eu não posso acreditar que esta é a única maneira de fazê-lo.
Eu também encontrei um pequeno aplicativo na internet chamado PEView , mas mostra muito (e inútil no meu caso) informações e não é um aplicativo de linha de comando.
objdump empacotado dentro Cygwin também pode despejar algumas informações sobre os arquivos DLL, mas eu posso não vir a opção para despejar versão DLL. Note-se que MajorImageVersion, MinorImageVersion e outros campos despejado por esta ferramenta (com opção -p) não estão relacionados com a própria versão DLL.
Qualquer alternativas sobre o que fazer? Talvez eu tenha perdido alguma opção objdump importante? É Mt.exe minha única opção? Se este for o caso, é possível obtê-lo separadamente do Windows SDK?
Solução
Você também pode olhar para Filever.exe, que pode ser baixado como parte do ferramentas de suporte do Windows XP SP2 pacote -. única 4.7MB de download
Outras dicas
Você pode usar o PowerShell para obter as informações desejadas.
(Get-Item C:\Path\To\MyFile.dll).VersionInfo
Por padrão isto irá mostrar ProductVersion e FileVersion Mas a completa VERSIONINFO está disponível. Ou seja, para retornar Comentários
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments
Use Microsoft Sysinternals SigCheck . Esta saídas de amostra apenas a versão:
sigcheck -q -n foo.dll
sigcheck.exe desembalado apenas 228 KB.
Você pode escrever um script VBScript para obter a informação de versão de arquivo:
VersionInfo.vbs
set args = WScript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetFileVersion(args(0))
Wscript.Quit
Você pode chamar isso na linha de comando como este:
cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll
ou você pode construir um você mesmo. Abrir VS, crie um novo aplicativo de console. Crie um projeto simples, sem ATL ou suporte MFC, deixe a opção stdafx marcada, mas não marque 'projeto vazio' e chamá-lo VersionInfo.
Você vai ter um projeto simples com 2 arquivos: VersionInfo.cpp e VersionInfo.h
Abra o arquivo cpp e cole o seguinte para ele, em seguida, compilar. Você vai ser capaz de executá-lo, o primeiro argumento é o nome do arquivo completo, ele vai imprimir "produto: 5.6.7.8 do arquivo: 1.2.3.4" baseado no bloco de recursos Version. Se não houver recurso versão que vai retornar -1, caso contrário 0.
compila para um 8k binário usando o CRT dll, 60k com tudo incluído estaticamente (definido no C ++ opções, altere "Geração de código página, as opções de tempo de execução" para "/ MT")
HTH.
PS. Se você não quiser usar Visual Studio, ele ainda vai compilar usando qualquer compilador c ++ (dedos cruzados), mas você quase certamente tem que mudar a #pragma - apenas especificar que lib nas configurações do vinculador em vez disso, é a Pragma apenas um atalho para automaticamente ligar com essa biblioteca.
// 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
As ferramentas ListDLLs de Systernals pode fazer o trabalho: http: // TechNet. microsoft.com/en-us/sysinternals/bb896656.aspx
listdlls -v -d mylib.dll
Esta função retorna os detalhes do arquivo NTFS do Windows para qualquer arquivo usando Cygwin bash (real r-click-propriedades-Info) para o termo
Passe o caminho arquivos para finfo (), pode ser caminho UNIX, DOS caminho, relativo ou absoluto. O arquivo é convertido em um caminho nix absoluta, então verificado para ver se ele é em verdade a / arquivo regular existente. Então convertido em um caminho de janelas absolutos e enviado para "wmic". Então a mágica, você tem detalhes do arquivo janelas direita no terminal. Usos: cygwin, cygpath, sed e awk. Precisa do Windows WMI "Wmic.exe" para ser operacional. A saída é corrigida para fácil ...
$ 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" }'
}
Usando PowerShell é possível obter apenas a cadeia de versão, ou seja, 2.3.4 a partir de qualquer dll ou exe com o seguinte comando
(Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion
Testado em Windows 10
Existe um aplicativo de linha de comando chamado "ShowVer" no CodeProject:
ShowVer.exe de linha de comando programa de exibição VERSIONINFO
Como de costume a aplicação vem com um exe eo código fonte (VisualC ++ 6).
Fora saídas de todos os metadados disponíveis:
Em um sistema alemão Win7 a saída para user32.dll é assim:
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
e uma maneira com 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*"
exemplo de saída (tem uma versão corda que é um pequeno acréscimo ao método 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
e mais uma Usando Shell.Application e híbridos lote \ de jscript.Here 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();
usado contra 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