Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Access violation при чтении версии, Access violation при чтении версии 
:(
    Опции темы
Sur0vy
Дата 20.1.2012, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 1.10.2009

Репутация: нет
Всего: нет



Доброго времени суток!

Определяю версию программы, используя библиотеку jedi
Код примерно такой:

Код

.
.
.
private
    Vers: TJvVersionInfo;
    LongVers: TLongVersion;
.
.
.
procedure TfrmAbout.FormCreate(Sender: TObject);
begin
  Vers:= TJvVersionInfo.Create('MyEXE.exe');
end;

procedure TFrmAbout.FormShow(Sender: TObject);
begin
  LongVers:= StringToLongVersion(Vers.FileVersion);
  lblVersion.Caption:= IntTostr(LongVers.All[2]) + '.' + IntTostr(LongVers.All[1]) + '.' + IntTostr(LongVers.All[3]);
end;


Работает нормально на компьютере, где установлена среда, запускаю на любом другом компьютере Access violation
Но это только часть проблемы, добавляю к коду одну строку

Код

.
.
.
private
    Vers: TJvVersionInfo;
    LongVers: TLongVersion;
.
.
.
procedure TfrmAbout.FormCreate(Sender: TObject);
begin
  Vers:= TJvVersionInfo.Create('MyEXE.exe');
end;

procedure TFrmAbout.FormShow(Sender: TObject);
begin
  ShowMessage('111111111');
  LongVers:= StringToLongVersion(Vers.FileVersion);
  lblVersion.Caption:= IntTostr(LongVers.All[2]) + '.' + IntTostr(LongVers.All[1]) + '.' + IntTostr(LongVers.All[3]);
end;

И все наоборот: на моем компе с win7 и delphi xe2 вылетает, а на "чистой" XP все нормально работает.

Может было у кого-нибудь подобное волшебство? 

PM MAIL   Вверх
northener
Дата 20.1.2012, 15:58 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: 8
Всего: 20



Цитата(Sur0vy @  20.1.2012,  15:36 Найти цитируемый пост)
Может было у кого-нибудь подобное волшебство? 

Это не волшебство. Это нормальное поведение AV. Неверная работа с памятью не всегда приводит к AV. Так что не ищите разницы в компьютерах. Ишите саму ошибку.

Очень советую прочитать вот это. Причём полностью и вдумчиво.

Это сообщение отредактировал(а) northener - 21.1.2012, 01:32


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
Akella
Дата 20.1.2012, 17:23 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



Код

Type
  TFileInfo = Record
    CompanyName      : String;
    FileDescription  : String;
    FileVersion      : String;
    InternalName     : String;
    LegalCopyright   : String;
    LegalTradeMarks  : String;
    OriginalFileName : String;
    ProductName      : String;
    ProductVersion   : String;
    Comments         : String;
  end;



....


function TfmMain.xGetExeFileInfo(sAppName:string): TFileInfo;
type
  PTransBuffer = ^TTransBuffer;
  TTransBuffer = array[1..4] of smallint;
var
  iAppSize, iLenOfValue : DWord;
  pcBuf,pcValue         : PChar;
  VerSize               : DWord;
  pTrans                : PTransBuffer;
  TransStr              : string;
  fvip                  : pointer;
  i:Integer;
  const
  AK47 : array [0..9] of string = ('CompanyName','FileDescription','FileVersion',
                                   'InternalName','LegalCopyright', 'LegalTradeMarks',
                                   'OriginalFileName','ProductName',
                                   'ProductVersion','Comments' );
begin
  if not FileExists(sAppName) then exit;
     Result.CompanyName      := '';
     Result.FileDescription  := '';
     Result.FileVersion      := '';
     Result.InternalName     := '';
     Result.LegalCopyright   := '';
     Result.LegalTradeMarks  := '';
     Result.OriginalFileName := '';
     Result.ProductName      := '';
     Result.ProductVersion   := '';
     Result.Comments         := '';

  // get version information values
  iAppSize:= GetFileVersionInfoSize(PChar(sAppName),// pointer to filename string
                                    iAppSize);      // pointer to variable to receive zero
   // if GetFileVersionInfoSize is successful
  if iAppSize > 0 then
  begin
      pcBuf := AllocMem(iAppSize);
      GetFileVersionInfo(PChar(sAppName),              // pointer to filename string
                         0,                            // ignored
                         iAppSize,                     // size of buffer
                         pcBuf);                       // pointer to buffer to receive file-version info.

      VerQueryValue(pcBuf, '\', fvip, iLenOfValue);
      VerQueryValue(pcBuf, PChar('\VarFileInfo\Translation'),pointer(ptrans), verSize);
      TransStr:= IntToHex(ptrans^[1], 4) + IntToHex(ptrans^[2], 4);

      for i:=0 to 9 do
      begin
        Case i of
          0: if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
               Result.CompanyName := pcValue;
          1: if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
               Result.FileDescription := pcValue;
          2: if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
               Result.FileVersion := pcValue;
          3:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
              Result.InternalName := pcValue;
          4:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
               Result.LegalCopyright  :=  pcValue;
          5:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
              Result.LegalTradeMarks :=pcValue;
          6:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
             Result.OriginalFileName := pcValue;
          7:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
             Result.ProductName := pcValue;
          8:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
              Result.ProductVersion := pcValue;
          9:if VerQueryValue(pcBuf,PChar('StringFileInfo\' + TransStr + '\' + AK47[i] ), Pointer(pcValue),iLenOfValue) then
              Result.Comments := pcValue;
        end;//case
      end;
      FreeMem(pcBuf,iAppSize);
  end;
end;






//использование

Var
 FI : TFileInfo;
begin
  FI := xGetExeFileInfo(ParamStr(0));
  LabelVersion.Caption := constVersion + fi.FileVersion;


PM MAIL   Вверх
superVad
Дата 20.1.2012, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 735
Регистрация: 6.4.2006
Где: Черкассы, Украина

Репутация: 4
Всего: 15



Sur0vy, на какой строчке вылетает тот самый АВ? Без этой информации можно долго гадать.
Если на другом компе нету делфи, то хотя бы по вставляй туда шоумеседжей, что бы определить...
PM MAIL   Вверх
Keeper89
Дата 21.1.2012, 01:42 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Надо бы добавить проверку на успешность получения версии, как-то так:
Код

procedure TForm1.FormCreate(Sender: TObject);
var
  JvVersionInfo: TJvVersionInfo;
  LongVersion: TLongVersion;
begin
  JvVersionInfo := TJvVersionInfo.Create('Project1.exe');
  try
    if JvVersionInfo.Valid then
    begin
      LongVersion := StringToLongVersion(JvVersionInfo.FileVersion);
      Caption := Format('%d.%d.%d', [LongVersion.All[2], LongVersion.All[1], LongVersion.All[3]]);
    end;
  finally
    FreeAndNil(JvVersionInfo);
  end;
end;


Это сообщение отредактировал(а) Keeper89 - 21.1.2012, 01:44


--------------------
PM MAIL WWW   Вверх
northener
Дата 21.1.2012, 02:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: 8
Всего: 20



Извращенцы!

Зачем вам понадобилось помощь джедаев, чтобы получить полную информацию о версии программы?


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
Keeper89
Дата 21.1.2012, 04:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Подключили всего один модуль, а ты сразу извращенцы smile

Хорошая объектная обертка. А кому нужна диета - можно прям вырезать GetFileVersionInfo оттуда, вот как вариант.


--------------------
PM MAIL WWW   Вверх
БелАмор
Дата 21.1.2012, 11:10 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 5
Всего: 17



Цитата(Sur0vy @  20.1.2012,  15:36 Найти цитируемый пост)
  Vers:= TJvVersionInfo.Create('MyEXE.exe');

1. Поиск чего-либо в текущем каталоге - путь мазохиста. Указывайте полный путь. Текущий каталог может смениться в любой момент. В частности, его меняют все диалоги открытия/сохранения файлов, имеющие настройки по умолчанию.
2. Указание литералом того, что можно получать автоматически - плохой стиль.
3. Полное имя своего исполняемого файла можно получить либо из командной строки ParamStr(0), либо из свойства Application.ExeName


Это сообщение отредактировал(а) БелАмор - 21.1.2012, 11:22
PM   Вверх
Akella
Дата 21.1.2012, 14:46 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



и чем же вам мой вариант не подходит?

Добавлено через 25 секунд
а джедаев используют только мазохисты
PM MAIL   Вверх
Snowy
Дата 21.1.2012, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



А я всегда советовал брать свою версию из ресурса, а не обращаться к своему файлу.
PM MAIL   Вверх
CodeMonkey
Дата 21.1.2012, 16:26 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Есть мнение, что если человек не может разобраться с объектной обёрткой, то программирование на WinAPI для него - вообще труба. 


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Akella
Дата 21.1.2012, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



Цитата(Snowy @ 21.1.2012,  16:13)
А я всегда советовал брать свою версию из ресурса, а не обращаться к своему файлу.

Цитата

Много замечательных программ, написано на дельфи. Вот ещё в копилку.
Медиаплейеры, написанные на Delphi:

PM MAIL   Вверх
Keeper89
Дата 21.1.2012, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Цитата(Akella @  21.1.2012,  14:46 Найти цитируемый пост)
а джедаев используют только мазохисты 

Хоть кто-то аргументирует? smile


--------------------
PM MAIL WWW   Вверх
gesper
Дата 22.1.2012, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


"Shарфик"
*


Профиль
Группа: Участник
Сообщений: 183
Регистрация: 23.2.2005

Репутация: 1
Всего: 2



Чем плох такой вариант, как то не разбирался в нем досканально, но давно очень использую и на всех ОС работал, зачем куча кода?

Код

function GetVersion: string;
 var
   VerInfoSize: DWORD;
   VerInfo: Pointer;
   VerValueSize: DWORD;
   VerValue: PVSFixedFileInfo;
   Dummy: DWORD;
 begin
   VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
   GetMem(VerInfo, VerInfoSize);
   GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
   VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
   with VerValue^ do
   begin
     Result := IntToStr(dwFileVersionMS shr 16);
     Result := Result + '.' + IntToStr(dwFileVersionMS and $FFFF);
     Result := Result + '.' + IntToStr(dwFileVersionLS shr 16);
     Result := Result + '.' + IntToStr(dwFileVersionLS and $FFFF);
   end;
   FreeMem(VerInfo, VerInfoSize);
end;

--------------------
...И приколется обломившийся и oбломится приколовшийся...
PM MAIL   Вверх
northener
Дата 22.1.2012, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: 8
Всего: 20



Цитата(Keeper89 @  21.1.2012,  23:32 Найти цитируемый пост)
Хоть кто-то аргументирует?

Я лично такого не говорил. Более того у джедаев есть весьма много полезного и весьма грамотного. Особенно если использовать их наработки с умом. Возможно используя их библиотеку (начиная с времен RxLib и до нынешнего времени) не столько напрямую, сколько просматривая её исходный код в "учебных" целях.
Но вот использовать их компоненты для получения номера версии программы просто глупо. Ведь с помощью WinAPI реализовать получение данной информации возможно на любой версии Дельфи начиная с истоков (т.е. Д1)! И даже в Д1, где приходилось делать "лишние телодвижения" для преобразовании string в PChar и наоборот, такой код состоит из всего 9 строчек!!!

Цитата(CodeMonkey @  21.1.2012,  16:26 Найти цитируемый пост)
Есть мнение, что если человек не может разобраться с объектной обёрткой, то программирование на WinAPI для него - вообще труба. 

Соглашусь в целом, но не в данном случае. Ссылок на пример получения версии программы через WinAPI во всемирной помойке - миллион и ещё маленькая тележка. И разобраться в этих примерах гораздо проще, ибо те три функции WinAPI, которые там используются достаточно нормально документированы. А вот сторонние "обёртки", как правило страдают в этом плане.

Добавлено @ 00:36
Цитата(gesper @  22.1.2012,  00:13 Найти цитируемый пост)
Чем плох такой вариант

Страдает он только неграмотной работой с функциями WinAPI. Это я бы сказал "вариант новичка". Функции WinAPI в данном коде используются как процедуры. Т.е. "Авось и так сойдёт, а писать лишний код лень, да и не понятно как".

Это сообщение отредактировал(а) northener - 22.1.2012, 00:51


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0649 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.