PythonでEXEファイルのバージョン取得
Windows環境のPythonで、EXEファイルやDLLファイルのバージョンを調べようと思ったとき、ctypesをうまく使うことで、簡単にバージョン情報を手に入れることができたので、記述しておこうと思います。
そもそも、WindowsでC++プログラミングをしていても、バージョンを取得するにはversion.libをソフトウェアに抱えるか、version.dllを呼び出す必要があるようです。
version.dllには、バージョンを扱うための関数GetFileVersionInfoSize、GetFileVersionInfo、VerQueryValueが含まれています。
これをPythonで利用することで、EXEやDLLのバージョン取得を容易に行うことができるようになります。
#!/usr/bin/env python # coding: utf-8 import array from ctypes import * def get_file_version(file_name = '', info = ''): if '' == file_name or '' == info: return '' # get file version size size = windll.version.GetFileVersionInfoSizeA(file_name, None) if not size: return '' # create buffer res = create_string_buffer(size) # get file version info windll.version.GetFileVersionInfoA(file_name, None, size, res) r = c_uint() l = c_uint() # query value windll.version.VerQueryValueA(res, '\\VarFileInfo\\Translation', byref(r), byref(l)) if not l.value: return '' # create array codepages = array.array('H', string_at(r.value, l.value)) codepage = tuple(codepages[:2].tolist()) # query value windll.version.VerQueryValueA(res, ('\\StringFileInfo\\%04x%04x\\' + info) % codepage, byref(r), byref(l)) return string_at(r.value, l.value) if __name__ == '__main__': file_name = 'C:\\windows\\system32\\notepad.exe' info = 'FileVersion' version = get_file_version(file_name, info) print('%s: %s' % (file_name, version))
GetFileVersionInfoAの4番目の引数は文字列型のポインタなのですが、これはスクリプト側でcreate_string_bufferしておく必要があるようです。
一回目のVerQueryValueAで、OSの言語のコードページというものを取得します。
二回目のVerQueryValueAで、先ほどのコードページを元にして、バージョンを手に入れます。
このスクリプトを実行するとnotepadのバージョンを出力します。
Pythonのライブラリには、「Win32 Extensions for Python」を使ってもできそうです。
ただ、バージョン確認のためだけに、ライブラリをインストールするのは忍びないという方は、今回のスクリプトを使うと良いと思います。
他にもctypesを利用すれば、いろいろなWin32 APIを利用できるようなので、調査すると良いかもしれませんね。