![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Хочу получить версию файла, но(+) [D5, Win2k]
UNIVERSAL © (2004-03-18 11:14:00)...но если я эту функцию выполняю в простом проекте, то всё ок. по крайней мере нет exception-ов и прога нормально регирует, но если я её пихаю в DLL, а потом делаю вызов, то происходит exception. Вопрос, как обычно, что я делаю не так?
Код в DLL
function GetFileInfoValue(lpData:Pointer; LanguageInfo:string; From: string): string;stdcall;
var str:pchar;dstr:cardinal;
begin
//Константа From может быть следующей: "CompanyName", "FileDescription",
//"FileVersion", "InternalName", "LegalCopyright", "OriginalFilename",
//"ProductName","ProductVersion", "Comments"
VerQueryValue(lpData,pchar('\StringFileInfo\'+LanguageInfo+'\'+From),
pointer(str), dstr);
if dstr>0 then Result := str else Result := '';
end;
function GetFileInfo(FileName:string;What:string):string;stdcall;
var DataSize:cardinal; Trans,lpData:Pointer;temp:cardinal;FLanguageInfo,LangCharSet:string;
h:cardinal;TransSize:cardinal;
begin
DataSize:=GetFileVersionInfoSize(PChar(Filename),h);
if DataSize>0 then
begin
//Здесь, Filename - имя файла, содержащего версию файла, а BuffSize - переменная, в которую будет записано количество байт, занимаемых информацией о версии. Функция запишет в переменную BuffSize число меньшее 1, если информация о версии отсутствует или произошла ошибка.
//После этого, выделив буфер, мы запрашиваем сам блок информации о версии файла.
lpData:=AllocMem(DataSize);
GetFileVersionInfo(pchar(Filename) ,cardinal(0),DataSize,lpData);
//Но это еще не все. Информация о версии является многоязычным ресурсом, поэтому следует узнать список языков, которые поддерживаются версией файла.
VerQueryValue(lpData,'\VarFileInfo\Translation', Trans,TransSize);
if TransSize>=4 then
begin
temp:=0;
StrLCopy(@temp, pchar(Trans), 2);
LangCharSet:=IntToHex(temp, 4);
StrLCopy(@temp, pchar(Trans)+2, 2);
FLanguageInfo := LangCharSet+IntToHex(temp, 4);
//Выяснив язык, запрашиваем информацию, которая требуется при помощи вот такой функции:
Result:=GetFileInfoValue(lpData, FLanguageInfo,What);
end else Result:=''
end else Result:='';
freemem(lpData);
end;
код в проекте
function GetFileInfo(FileName:string;What:String):string; external 'pf.dll' name 'GetFileInfo';
procedure TForm1.Button2Click(Sender: TObject);
var fv:string;
begin
// fv:=GetFileInfo('c:\alphapri\alphatab.mdb','FileVersion');
fv:=GetFileInfo('D:\WINNT\system32\notepad.exe','FileVersion');
MessageBox(0,PChar(fv),nil,MB_OK );
end;
VMcL (2004-04-28 14:57:00) [1]>>BiN © (28.04.04 14:37) [25]
Возможно. Я в VB не силён.
BiN (2004-04-28 14:37:00) [2]VMcL © (27.04.04 16:52) [24]
IMHO, все-таки ошибаетесь.
Пример работает, пока вызываем MessageBox A.
Private Declare Function MessageBox Lib "user32" _
Alias "MessageBoxA" (ByVal Handle As Long, _
ByVal lpText As String, ByVal lpCaption As String, _
ByVal Flag As Long) As Long
Public Sub MySub()
MessageBox 0, "Text", "Caption", 0
End Sub
VMcL (2004-04-27 16:52:00) [3]>>UNIVERSAL (19.03.04 09:49) [10]
AFAIK, String в VB - это WideString (PWideChar) в Delphi.
Mikle (2004-04-27 13:57:00) [4]посмотрите на эту тему
http://forum.sources.ru/index.php?showtopic=40118
BiN (2004-03-22 09:34:00) [5]Нет не знал. просвети плз.
в меню Run->Parameters в качестве "Host Apllication" ставишь имя программы, кот. будет загружать твою dll. Жмешь OK. Затем ставишь точки останова в тексте проекта и жмешь F9. Я правда не уверен, что именно в случае с VB нужно прописывать - может cscript.exe или wscript.exe, но может и что-то другое, не помню
UNIVERSAL (2004-03-22 08:17:00) [6]1. Да уже убирал.
2 и стринг этот уже :))) от отчаяния написал как и п2.
Нет не знал. просвети плз.
Код вызова:
Dim v As String, l As Long, bs As Integer, fst As Date
bs = 200
v = String(bs, Chr(0))
l = GetFileInfo(ByVal rsUpdate.Fields("Source").Value, ByVal "FileVersion", ByVal v, ByVal bs)
в принципе вызов уже тоже как только не пробовался и с ByVal и без него. rsUpdate.Fields("Source").Value - это полное имя файла.
BiN (2004-03-19 15:56:00) [7]1. убери var в "... var R:PChar;"
2. что это такое R1:= string(GetFileInfoValue(lpData, PChar(FLanguageInfo),What));
А заодно приведи код вызова этой функции в VB(надеюсь модеры это простят :))
Да, и давно хотел тебя спросить, ты знаешь, что можно отлаживать и Dll?
UNIVERSAL (2004-03-19 15:43:00) [8]Код в DLL
function GetFileInfo( const FileName, What:PChar; var R:PChar;BuffSize:integer):integer;stdcall;
var DataSize:cardinal; Trans,lpData:Pointer;temp:cardinal;FLanguageInfo,LangCharSet:string;
h:cardinal;TransSize:cardinal;r1:string; // f:text;
begin
DataSize:=GetFileVersionInfoSize(Filename,h);
if DataSize>0 then
begin
//Здесь, Filename - имя файла, содержащего версию файла, а BuffSize - переменная, в которую будет записано количество байт, занимаемых информацией о версии. Функция запишет в переменную BuffSize число меньшее 1, если информация о версии отсутствует или произошла ошибка.
//После этого, выделив буфер, мы запрашиваем сам блок информации о версии файла.
lpData:=AllocMem(DataSize);
GetFileVersionInfo(Filename ,cardinal(0),DataSize,lpData);
//Но это еще не все. Информация о версии является многоязычным ресурсом, поэтому следует узнать список языков, которые поддерживаются версией файла.
VerQueryValue(lpData,'\VarFileInfo\Translation', Trans,TransSize);
if TransSize>=4 then
begin
temp:=0;
StrLCopy(@temp, pchar(Trans), 2);
LangCharSet:=IntToHex(temp, 4);
StrLCopy(@temp, pchar(Trans)+2, 2);
FLanguageInfo :=LangCharSet+IntToHex(temp, 4);
//Выяснив язык, запрашиваем информацию, которая требуется при помощи вот такой функции:
R1:=string(GetFileInfoValue(lpData, PChar(FLanguageInfo),What));
result:=length(R1);
move(r1[1],r[0],result);
end else R:='';
freemem(lpData);
end else R:='';
end;
Декларация
Public Declare Function GetFileInfo Lib "PF.dll" (ByVal FileName As String, ByVal What As String, ByVal R As String, ByVal buffsize As Long) As Long
UNIVERSAL (2004-03-19 15:39:00) [9]
function GetFileInfo( const FileName, What:PChar; var R:PChar;BuffSize:integer):integer;stdcall;
var DataSize:cardinal; Trans,lpData:Pointer;temp:cardinal;FLanguageInfo,LangCharSet:string;
h:cardinal;TransSize:cardinal;r1:string; // f:text;
begin
DataSize:=GetFileVersionInfoSize(Filename,h);
if DataSize>0 then
begin
//Здесь, Filename - имя файла, содержащего версию файла, а BuffSize - переменная, в которую будет записано количество байт, занимаемых информацией о версии. Функция запишет в переменную BuffSize число меньшее 1, если информация о версии отсутствует или произошла ошибка.
//После этого, выделив буфер, мы запрашиваем сам блок информации о версии файла.
lpData:=AllocMem(DataSize);
GetFileVersionInfo(Filename ,cardinal(0),DataSize,lpData);
//Но это еще не все. Информация о версии является многоязычным ресурсом, поэтому следует узнать список языков, которые поддерживаются версией файла.
VerQueryValue(lpData,'\VarFileInfo\Translation', Trans,TransSize);
if TransSize>=4 then
begin
temp:=0;
StrLCopy(@temp, pchar(Trans), 2);
LangCharSet:=IntToHex(temp, 4);
StrLCopy(@temp, pchar(Trans)+2, 2);
FLanguageInfo :=LangCharSet+IntToHex(temp, 4);
//Выяснив язык, запрашиваем информацию, которая требуется при помощи вот такой функции:
R1:=string(GetFileInfoValue(lpData, PChar(FLanguageInfo),What));
result:=length(R1);
move(r1[1],r[0],result);
end else R:='';
freemem(lpData);
end else R:='';
end;
Декларация
Public Declare Function GetFileInfo Lib "PF.dll" (ByVal FileName As String, ByVal What As String, ByVal R As String, ByVal buffsize As Long) As Long
UNIVERSAL (2004-03-19 15:38:00) [10]
function GetFileInfo( const FileName, What:PChar; var R:PChar;BuffSize:integer):integer;stdcall;
var DataSize:cardinal; Trans,lpData:Pointer;temp:cardinal;FLanguageInfo,LangCharSet:string;
h:cardinal;TransSize:cardinal;r1:string; // f:text;
begin
DataSize:=GetFileVersionInfoSize(Filename,h);
if DataSize>0 then
begin
//Здесь, Filename - имя файла, содержащего версию файла, а BuffSize - переменная, в которую будет записано количество байт, занимаемых информацией о версии. Функция запишет в переменную BuffSize число меньшее 1, если информация о версии отсутствует или произошла ошибка.
//После этого, выделив буфер, мы запрашиваем сам блок информации о версии файла.
lpData:=AllocMem(DataSize);
GetFileVersionInfo(Filename ,cardinal(0),DataSize,lpData);
//Но это еще не все. Информация о версии является многоязычным ресурсом, поэтому следует узнать список языков, которые поддерживаются версией файла.
VerQueryValue(lpData,'\VarFileInfo\Translation', Trans,TransSize);
if TransSize>=4 then
begin
temp:=0;
StrLCopy(@temp, pchar(Trans), 2);
LangCharSet:=IntToHex(temp, 4);
StrLCopy(@temp, pchar(Trans)+2, 2);
FLanguageInfo :=LangCharSet+IntToHex(temp, 4);
//Выяснив язык, запрашиваем информацию, которая требуется при помощи вот такой функции:
R1:=string(GetFileInfoValue(lpData, PChar(FLanguageInfo),What));
result:=length(R1);
move(r1[1],r[0],result);
end else R:='';
freemem(lpData);
end else R:='';
end;
Декларация
Public Declare Function GetFileInfo Lib "PF.dll" (ByVal FileName As String, ByVal What As String, ByVal R As String, ByVal buffsize As Long) As Long
BiN (2004-03-19 15:10:00) [11]кофейная гуща, кАпание воском, карты, хиромантия... на чем еще гадать будем :)
приведи декларацию функции и еще раз желательно код (обновленный)
UNIVERSAL (2004-03-19 15:05:00) [12]К сожалению приложение выдаёт ошибку и некорректно завершает свою работу. Как я выяснил из-за строки Move(strRes[1], lpBuffer[0], pdwTotal^);заменил на Move(strRes, lpBuffer, pdwTotal^);выдаёт тоже, что и раньше краказяблы какие-то.
UNIVERSAL (2004-03-19 12:42:00) [13]Я пробовал примерно так, но видимо не всё учел.Спасибо попробую.
BiN (2004-03-19 12:31:00) [14]Вот примерный каркас твоей функци
function GetStr(lpStr:Pchar; lpBuffer:Pchar; dwBufferSize:DWORD; pdwTotal:PDWORD):BOOL;stdcall;
var
strRes:string;
begin
Result:=False;
if pdwTotal=nil then exit;
strRes:=lpStr;
//Здесь обрабатываем строку strRes
pdwTotal^:=Length(strRes);
if pdwTotal^>dwBufferSize then Exit;
if pdwTotal^>0 then
Move(strRes[1], lpBuffer[0], pdwTotal^);
Result:=True;
end;
UNIVERSAL (2004-03-19 11:24:00) [15]Вот опять наверное глупый вопрос:
Привёл я к виду этому, а что внутри со строкой и её буфером делать-то? я возвращяю длину нового буфера и эта длина правильная, только в переменной ерунда какая-то : <ьK\x5\x1\x1\x1\x1\x1, а должно быть 1.00.0006
BiN (2004-03-19 09:53:00) [16]а ты к какой форме привел свою функцию внутри длл? сделал так, как тебе посоветовали в [6]? - тогда явно ты неправильно объявляешь ее в VB
UNIVERSAL (2004-03-19 09:49:00) [17]Наверное это уже не сюда, но всё-таки может кто чё посоветует. Из делфей всё ОК (большое спасибо за помощь), а в VB не хочет передаваться результат работы ф-ии.Как я уже говорил я сделал log-файл. Из него видно что Result функции присваивается нормально, но в приложение попадает пустая строка. Обявление в VB:
Public Declare Function GetFileInfo Lib "PF.dll" (ByVal FileName As String, ByVal What As String) As String
вот как входные параметры String видимо прокатывает, а как рез-т функции или выходной параметр не хочет. Буду рыть доки, но если кто поможет буду благодарен.
UNIVERSAL (2004-03-19 08:33:00) [18]<2BIN>Спасибо. Точно-забыл.Из Делфей заработало. Теперь надо чтобы из VB заработало. Вообще-то это DLL для использования в VB.
BiN (2004-03-18 17:25:00) [19]По-моему, ты забыл в программе в объявлении функциии добавить stdcall
UNIVERSAL (2004-03-18 16:49:00) [20]Уже не зная что делать, сделал log файл, к-ый пишется из DLL. Так вот там вместо входных параметров белеберда какая-то. С чем может быть связано?
передаю вот так
....
var fn,i,fv:pchar;
fn:='D:\Production\Merchandiser\Merchandiser.exe';
i:='FileVersion';
fv:=GetFileInfo(Pointer(fn),Pointer(i));
....