2009-03-02 10 views
53

Tôi cần một công cụ dòng lệnh để loại bỏ thông tin phiên bản Windows DLL chuẩn để tôi có thể xử lý nó bằng một tập lệnh bash (Cygwin).Công cụ dòng lệnh để đổ phiên bản Windows DLL?

Là nhà phát triển Java, tôi không quen với các công cụ phát triển của Microsoft (mặc dù tôi có một chút kinh nghiệm với Microsoft Visual Embedded C++ 4.0 và Microsoft Visual Basic 6.0).

Công cụ thích hợp có vẻ là mt.exe, dưới dạng stated on SO. Tuy nhiên, cơ hội duy nhất tôi tìm thấy để có được ứng dụng nhỏ này là tải xuống ISO 1,29 GB của Windows SDK for Windows Server 2008 and .NET Framework. Tôi không thể tin đây là cách duy nhất để làm điều đó.

Tôi cũng tìm thấy một ứng dụng nhỏ trên Internet được gọi là PEView, nhưng nó hiển thị thông tin quá nhiều (và vô dụng trong trường hợp của tôi) và nó không phải là một ứng dụng dòng lệnh.

Chuẩn objdump đi kèm bên trong Cygwin cũng có thể đổ một số thông tin về tệp DLL, nhưng tôi không thể thấy tùy chọn để hủy phiên bản DLL. Lưu ý rằng MajorImageVersion, MinorImageVersion và các trường khác được đổ bởi công cụ này (với tùy chọn -p) không liên quan đến phiên bản DLL riêng.

Bất kỳ lựa chọn thay thế nào về việc cần làm? Có lẽ tôi đã bỏ lỡ một số tùy chọn objdump quan trọng? Có phải mt.exe là lựa chọn duy nhất của tôi không? Nếu trường hợp này xảy ra, bạn có thể nhận riêng nó từ Windows SDK không?

Trả lời

9

Bạn cũng có thể xem filever.exe, có thể tải xuống như một phần của gói Windows XP SP2 Support Tools - chỉ 4,7MB tải xuống (hoặc trực tiếp từ here).

+2

chỉ liệt kê chuyển đổi tệp, không phải các khía cạnh phiên bản khác. Thường thì bạn cũng cần phiên bản sản phẩm. 'sigcheck' (như những lời đề cập của uvts_cvs) cũng cho thấy những điều đó và tải xuống nhỏ hơn nhiều. –

45

Bạn có thể viết một kịch bản VBScript để có được những thông tin phiên bản file:

VersionInfo.vbs

set args = WScript.Arguments 
Set fso = CreateObject("Scripting.FileSystemObject") 
WScript.Echo fso.GetFileVersion(args(0)) 
Wscript.Quit 

Bạn có thể gọi đây là từ dòng lệnh như thế này:

cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll 
+0

Dường như khả thi bằng phương tiện của tập lệnh dòng lệnh. Cảm ơn –

10

hoặc bạn có thể tự mình xây dựng. Mở VS, tạo một ứng dụng giao diện điều khiển mới. Tạo một dự án đơn giản không có hỗ trợ ATL hoặc MFC, hãy chọn tùy chọn stdafx nhưng không chọn 'empty project' và gọi nó là VersionInfo.

Bạn sẽ nhận được một dự án đơn giản với 2 tác phẩm: VersionInfo.cpp và VersionInfo.h

Mở tập tin cpp và dán đoạn mã sau vào nó, sau đó biên dịch. Bạn sẽ có thể chạy nó, đối số đầu tiên là tên đầy đủ, nó sẽ in ra "Sản phẩm: 5.6.7.8 Tệp: 1.2.3.4" dựa trên khối tài nguyên Phiên bản. Nếu không có tài nguyên phiên bản, nó sẽ trả về -1, nếu không 0.

Biên dịch thành nhị phân 8k bằng CRT dll, 60k với mọi thứ được liên kết tĩnh (đặt trong tùy chọn C++, thay đổi "Trang tạo mã, tùy chọn thời gian chạy" thành "/ MT")

HTH.

PS. Nếu bạn không muốn sử dụng Visual Studio, nó sẽ vẫn biên dịch bằng cách sử dụng bất kỳ trình biên dịch C++ nào (các dấu vân tay), nhưng bạn gần như chắc chắn phải thay đổi #pragma - chỉ cần chỉ định lib đó trong cài đặt trình liên kết thay thế, chỉ là một cách viết tắt để tự động liên kết với thư viện đó.


// 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; 
} 
+0

Không chính xác những gì tôi đang tìm kiếm, nhưng vẫn thú vị để phát triển một chương trình nhỏ để làm điều đó. Cảm ơn. –

+1

không? Bạn muốn thông tin phiên bản nào? AFAIK Windows chỉ có thông tin phiên bản được lưu trữ trong các khối tài nguyên - đây là những gì bạn thấy khi bạn mở các thuộc tính trong trình khám phá. – gbjbaanb

+1

Bravo! Tôi cũng thích phát triển bánh xe :) – divinci

55

Sử dụng Microsoft Sysinternals Sigcheck. Mẫu này chỉ xuất ra phiên bản:

sigcheck -q -n foo.dll 

Uniged sigcheck.exe chỉ 228 KB.

+3

349 KB năm năm sau ... vẫn còn giá trị nó? ;) – Ben

1

Có một ứng dụng dòng lệnh gọi là "ShowVer" tại CodeProject:

ShowVer.exe command-line VERSIONINFO display program

Như thường lệ các ứng dụng đi kèm với một exe và mã nguồn (VisualC++ 6).

Out đầu ra tất cả các dữ liệu meta có sẵn:

Trên một hệ thống Win7 Đức đầu ra cho user32.dll là như thế này:

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 
77

Bạn có thể sử dụng PowerShell để có được những thông tin mà bạn muốn.

(Get-Item C:\Path\To\MyFile.dll).VersionInfo 

Theo mặc định này sẽ hiển thị ProductVersion và FileVersion Nhưng toàn bộ VERSIONINFO có sẵn. I E. để trở Comments

(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments 
+2

Đây phải là câu trả lời. Đó là câu trả lời duy nhất không dựa vào các công cụ out-of-box. –

+7

Pipe to fl * để nhận tất cả các thuộc tính VersionInfo: PS C: \> (Get-Item C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe) .VersionInfo | fl * – Glenn

+0

Sử dụng số này tôi nhận 0 cho số phiên bản và sai cho tất cả các thuộc tính Is *. – NobleUplift

9
C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version 
Version 
6.1.7601.18229 
+0

Điều này chỉ hoạt động trên trường hợp = dll phải được tải. –

+0

Và bạn phải ở trong nhóm Quản trị viên để chạy nó. – neves

3

Hàm này trả về ntfs chi tiết tập tin Windows cho bất kỳ tập tin sử dụng Cygwin bash (thực tế r nhấp chuột -properties-info) với cụm từ

Chuyển đường dẫn tệp tới finfo(), có thể là đường dẫn unix, đường dẫn dos, tương đối hoặc tuyệt đối. Tệp được chuyển đổi thành một đường dẫn nix tuyệt đối, sau đó kiểm tra xem nó có trong thực tế là một tệp thông thường/hiện có hay không. Sau đó chuyển đổi thành một đường dẫn cửa sổ tuyệt đối và gửi đến "wmic". Sau đó, ma thuật, bạn có cửa sổ chi tiết tập tin ngay trong thiết bị đầu cuối. Công dụng: Cygwin, cygpath, sed, và awk. Cần Windows WMI "wmic.exe" để hoạt động. Đầu ra được điều chỉnh để dễ dàng ...

$ 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 "[email protected]")" ]] || { echo "bad-file"; return 1; } 
    echo "$(wmic datafile where name=\""$(echo "$(cygpath -wa "[email protected]")" | sed 's/\\/\\\\/g')"\" get /value)" |\ 
    sed 's/\r//g;s/^M$//;/^$/d' | awk -F"=" '{print $1"=""\033[1m"$2"\033[0m" }' 
} 
+0

FYI này wil trở lại Phiên bản = #### vì vậy chỉ cần lọc ra với một cái gì đó như: 'finfo file.dll | awk -F "=" '/ Phiên bản/{print $ 2}' 'hoặc' grep Phiên bản | cut -d '=' -f 2' Hoặc tốt hơn là thêm vào các chức năng để vượt qua các tùy chọn. tức là 'finfo -V file.dll' – jonretting

+1

Tại sao downvote khi op yêu cầu Cygwin bash. Ở đây nó ở dạng hàm, dọn dẹp các bit dos, định dạng nó một cách chính xác, và cung cấp thông tin cấp "wmic datafile" cho bất kỳ tệp nào được đưa ra. – jonretting

0

và một chiều với 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*" 

dụ đầu ra (nó có một chuỗi phiên bản mà là một bổ sung nhỏ với phương pháp 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 

và thêm một Sử dụng shell.application và batch lai \ jscript.Her e của 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(); 

dùng để chống lại 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