Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.06.06;
Скачать: CL | DM;

Вниз

Хочу получить версию файла, но(+)   Найти похожие ветки 

 
UNIVERSAL   (2004-03-18 11:14) [0]

...но если я эту функцию выполняю в простом проекте, то всё ок. по крайней мере нет 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;



 
BiN ©   (2004-03-18 11:21) [1]

LanguageInfo:string; From: string


 
UNIVERSAL   (2004-03-18 12:47) [2]

Не понял. Что через "," написать чтоли?


 
BiN ©   (2004-03-18 12:50) [3]

string замени на Pchar
когда создаешь dll в дельфи, внимательно читай комментарий сразу после строки library Project1;


 
UNIVERSAL   (2004-03-18 13:56) [4]

Большое спасибо попробую. Действительно облажался. Читайте доки они рулезные.


 
UNIVERSAL   (2004-03-18 15:18) [5]

Заменил все string на PChar. Ругань в таком диком формате прекратилась , но цель не достигнута. Теперь почему то возвращает всегда пустые строки, хотя версия файла точно есть и из приложения я её получаю из DLL - нет. Может ещё чем подскажите?


 
Игорь Шевченко ©   (2004-03-18 15:33) [6]

Потому что надо передавать в DLL адрес для буфера, куда будет класться нужная информация.
И функцию нужно объявить, как
 function GetFileInfo(const FileName, What: PChar; Buffer: PChar; BufferSize: Integer): Integer;stdcall;


Возвращать длину положенной в Buffer информации.
В DLL, вместо result использовать переданный буфер.


 
UNIVERSAL   (2004-03-18 16:49) [7]

Уже не зная что делать, сделал log файл, к-ый пишется из DLL. Так вот там вместо входных параметров белеберда какая-то. С чем может быть связано?
передаю вот так

....
var fn,i,fv:pchar;
fn:="D:\Production\Merchandiser\Merchandiser.exe";
i:="FileVersion";
fv:=GetFileInfo(Pointer(fn),Pointer(i));
....


 
BiN ©   (2004-03-18 17:25) [8]

По-моему, ты забыл в программе в объявлении функциии добавить stdcall


 
UNIVERSAL   (2004-03-19 08:33) [9]

<2BIN>Спасибо. Точно-забыл.Из Делфей заработало. Теперь надо чтобы из VB заработало. Вообще-то это DLL для использования в VB.


 
UNIVERSAL   (2004-03-19 09:49) [10]

Наверное это уже не сюда, но всё-таки может кто чё посоветует. Из делфей всё ОК (большое спасибо за помощь), а в VB не хочет передаваться результат работы ф-ии.Как я уже говорил я сделал log-файл. Из него видно что Result функции присваивается нормально, но в приложение попадает пустая строка. Обявление в VB:

Public Declare Function GetFileInfo Lib "PF.dll" (ByVal FileName As String, ByVal What As String) As String

вот как входные параметры String видимо прокатывает, а как рез-т функции или выходной параметр не хочет. Буду рыть доки, но если кто поможет буду благодарен.


 
BiN ©   (2004-03-19 09:53) [11]

а ты к какой форме привел свою функцию внутри длл? сделал так, как тебе посоветовали в [6]? - тогда явно ты неправильно объявляешь ее в VB


 
UNIVERSAL   (2004-03-19 11:24) [12]

Вот опять наверное глупый вопрос:
Привёл я к виду этому, а что внутри со строкой и её буфером делать-то? я возвращяю длину нового буфера и эта длина правильная, только в переменной ерунда какая-то : <ьK, а должно быть 1.00.0006


 
BiN ©   (2004-03-19 12:31) [13]

Вот примерный каркас твоей функци

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 12:42) [14]

Я пробовал примерно так, но видимо не всё учел.Спасибо попробую.


 
UNIVERSAL   (2004-03-19 15:05) [15]

К сожалению приложение выдаёт ошибку и некорректно завершает свою работу. Как я выяснил из-за строки Move(strRes[1], lpBuffer[0], pdwTotal^); заменил на Move(strRes, lpBuffer, pdwTotal^); выдаёт тоже, что и раньше краказяблы какие-то.


 
BiN ©   (2004-03-19 15:10) [16]

кофейная гуща, кАпание воском, карты, хиромантия... на чем еще гадать будем :)

приведи декларацию функции и еще раз желательно код (обновленный)


 
UNIVERSAL   (2004-03-19 15:38) [17]


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) [18]


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:43) [19]

Код в 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


 
BiN ©   (2004-03-19 15:56) [20]

1. убери var в "... var R:PChar;"
2. что это такое  R1:=string(GetFileInfoValue(lpData, PChar(FLanguageInfo),What));

А заодно приведи код вызова этой функции в VB(надеюсь модеры это простят :))
Да, и давно хотел тебя спросить, ты знаешь, что можно отлаживать и Dll?


 
UNIVERSAL   (2004-03-22 08:17) [21]

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-22 09:34) [22]

Нет не знал. просвети плз.

в меню Run->Parameters в качестве "Host Apllication" ставишь имя программы, кот. будет загружать твою dll. Жмешь OK. Затем ставишь точки останова в тексте проекта и жмешь F9. Я правда не уверен, что именно в случае с VB нужно прописывать - может cscript.exe или wscript.exe, но может и что-то другое, не помню


 
Mikle   (2004-04-27 13:57) [23]

посмотрите на эту тему
http://forum.sources.ru/index.php?showtopic=40118


 
VMcL ©   (2004-04-27 16:52) [24]

>>UNIVERSAL  (19.03.04 09:49) [10]

AFAIK, String в VB - это WideString (PWideChar) в Delphi.


 
BiN ©   (2004-04-28 14:37) [25]

VMcL ©   (27.04.04 16:52) [24]

IMHO, все-таки ошибаетесь.
Пример работает, пока вызываем MessageBoxA.


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-28 14:57) [26]

>>BiN ©  (28.04.04 14:37) [25]

Возможно. Я в VB не силён.



Страницы: 1 вся ветка

Текущий архив: 2004.06.06;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.056 c
4-1083243415
DoG
2004-04-29 16:56
2004.06.06
CreateNamedPipe


1-1084803085
SMART_n
2004-05-17 18:11
2004.06.06
Обмен данными между локальными приложениями


1-1085333904
k@rt
2004-05-23 21:38
2004.06.06
Куда пропадают сиволы?


1-1085546082
Глеб
2004-05-26 08:34
2004.06.06
Перемещение фокуса


14-1084771933
SergP
2004-05-17 09:32
2004.06.06
Хочу учиться.