Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 7, 2011 11:32:41

iFruty
От:
Зарегистрирован: 2011-06-07
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Получить FileInfo у dll и exe

собственно для реализации использую version.dll
есть код на сях который работает как надо. Пытаюсь переписать его на python
на сях:

// пример использования VerQueryValue
// вывод для avtapi.dl выглядит как:
/*
CompanyName: Корпорация Майкрософт
FileDescription: Программа вызова TAPI 3.0 и просмотра конференций многоадресной IP-рассылки
FileVersion: 5.1.2600.0 (xpclient.010817-1148)
InternalName: AVTAPI
LegalCopyright: c Корпорация Active Voice, 1998. Все права защищены.
LegalTradeMarks: нет информации
OriginalFilename: AVTAPI
ProductName: Операционная система MicrosoftR WindowsR
ProductVersion: 5.1.2600.0
Comments: нет информации
Author: нет информации
*/

#include <tchar.h>
#include <windows.h>
#include <stdio.h>

#pragma comment (lib, "version.lib") // указываем библиотеку, содержащую GetFileVersionInfoSize и т.п.

// наша функа
void PrintVersionStringInfo(const TCHAR *fileName)
{
PLONG infoBuffer; // буфер, куда будем читать информацию
DWORD infoSize; // и его размер

struct LANGANDCODEPAGE { // структура для получения кодовых страниц по языкам трансляции ресурсов файла
WORD wLanguage;
WORD wCodePage;
} *pLangCodePage;

// имена параметров, значения которых будем запрашивать
const TCHAR *paramNames[] = {
_T("CompanyName"),
_T("FileDescription"),
_T("FileVersion"),
_T("InternalName"),
_T("LegalCopyright"),
_T("LegalTradeMarks"),
_T("OriginalFilename"),
_T("ProductName"),
_T("ProductVersion"),
_T("Comments"),
_T("Author")
};

TCHAR paramNameBuf[256]; // здесь формируем имя параметра
TCHAR *paramValue; // здесь будет указатель на значение параметра, который нам вернет функция VerQueryValue
UINT paramSz; // здесь будет длина значения параметра, который нам вернет функция VerQueryValue

// получаем размер информации о версии файла
infoSize = GetFileVersionInfoSize(fileName, NULL);
if ( infoSize > 0 )
{
// выделяем память
infoBuffer = (PLONG) malloc(infoSize);

// получаем информацию
if ( 0 != GetFileVersionInfo(fileName, NULL, infoSize, infoBuffer) )
{
// информация находится блоками в виде "\StringFileInfo\кодовая_страница\имя_параметра
// т.к. мы не знаем заранее сколько и какие локализации (кодовая_страница) ресурсов имеются в файле,
// то будем перебирать их все
UINT cpSz;
// получаем список кодовых страниц
if ( VerQueryValue(infoBuffer, // наш буфер, содержащий информацию
_T("\\VarFileInfo\\Translation"),// запрашиваем имеющиеся трансляции
(LPVOID*) &pLangCodePage, // сюда функция вернет нам указатель на начало интересующих нас данных
&cpSz) ) // а сюда - размер этих данных
{
// перебираем все кодовые страницы
for (int cpIdx = 0; cpIdx < (int)(cpSz/sizeof(struct LANGANDCODEPAGE)); cpIdx++ )
{
// перебираем имена параметров
for (int paramIdx = 0; paramIdx < sizeof(paramNames)/sizeof(char*); paramIdx++)
{
// формируем имя параметра ( \StringFileInfo\кодовая_страница\имя_параметра )
_stprintf(paramNameBuf, _T("\\StringFileInfo\\%04x%04x\\%s"),
pLangCodePage[cpIdx].wLanguage, // ну, или можно сделать фильтр для
pLangCodePage[cpIdx].wCodePage, // какой-то отдельной кодовой страницы
paramNames[paramIdx]);

// получаем значение параметра
if ( VerQueryValue(infoBuffer, paramNameBuf, (LPVOID*)&paramValue, &paramSz));
// и выводим его на экран
/*
PrintRusLine(paramValue, paramNames[paramIdx]);
else
PrintRusLine(_T("нет информации"), paramNames[paramIdx]);*/
}
}
}
}

free(infoBuffer);
}
}

int _tmain(int argc, _TCHAR* argv[])
{
PrintVersionStringInfo( _T("d:\\user32.dll") );

return 0;
}
мой код на питоне (скорее всего корявый ибо 2 недели за ним)
import ctypes as ct
import struct
import sys


versionGetter = ct.windll.LoadLibrary("d:\\version.dll")
testfile = "d:\\user32.dll"

class LANGANDCODEPAGE(ct.Structure):
_fields_ = [("wLanguage", ct.c_ushort),
("wCodePage", ct.c_ushort)]

n = versionGetter.GetFileVersionInfoSizeW(testfile, 0)
print("FileVersionInfoSize: ", n)
infoBuffer = ct.create_string_buffer(n)
versionGetter.GetFileVersionInfoW(testfile, 0, n, ct.byref(infoBuffer))
tt = struct.unpack(str(n//4) + "L", infoBuffer)
print(tt)
cpSz = ct.c_uint(0)
langAndCodePage = LANGANDCODEPAGE(0, 0)

versionGetter.VerQueryValueW(infoBuffer, "\\VarFileInfo\\Translation", \
ct.byref(langAndCodePage), ct.byref(cpSz)) #КОСЯК ТУТ!
print("cpSz: ", cpSz.value)
print("wLanguage :", langAndCodePage.wLanguage, " wCodePage: ", langAndCodePage.wCodePage)
'''
buffer = ct.create_string_buffer(4)
versionGetter.VerQueryValueW(infoBuffer, "\\VarFileInfo\\Translation", \
buffer, ct.byref(cpSz))
print("cpSz: ", cpSz.value)
tt2 = struct.unpack("2H", buffer)
print(tt2)
'''
собственно по самой проблеме: значения переменных n, infoBuffer, cpSz - полностью совпадают с аналогичными значениями, которые выдает код на сях. Не те значения выдает langAndCodePage.wLanguage и langAndCodePage.wCodePage. При это значения у них всегда разные. В закомменченной части пробовал через буфер - собственно тоже самое и получается. Найти причину не получается - посему обращаюсь к опытным питонерам за помощью.



Отредактировано (Июнь 7, 2011 11:33:32)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version