Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 31.05.2015, 13:47
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Проблема с try except finally...

Здравствуйте!

Научите пожалуйста как правильно организовать исключения на примере следующей функции:

Код:
function ExtractRes(ResType, ResName, ResNewName : String):Boolean;
var
  Res: TResourceStream;
begin
  Result:= False;
  Res:=TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
  Res.SavetoFile(ResNewName);
  if FileExists(ResNewName) then Result:= True else Result:= False;
  Res.Free;
end;

Проблема в том, что в случае если не получается сохранить ресурс программа выдает соответствующее сообщение и после чего дальнейший код не выполняется...

а мне нужно вывести сообщение об этом, допустим:

Код:
if ExtractRes('EXEFILE','program', GetTempDir+'program.exe') then
   RichEdit.Text:= 'Файл распакован.'
else
   RichEdit.Text:= 'Файл НЕ распакован.';

В моем случае, если происходит ошибка распаковки ресурса то дальнейший код не выполняется... т.е. сообщения "Файл НЕ распакован." не видно...

Помогите грамотно переделать функцию пожалуйста. Буду вам очень признателен.
Ответить с цитированием
  #2  
Старый 31.05.2015, 15:41
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Если дело в эксепшене, то наверное как-то так.
Код:
try
  // unpack code
  Res.Free;
except
  Res.Free;
  Result := false;
end;
Ну или запихнуть все в общий try-finally, чтоб не дублировать Res.Free;
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 31.05.2015 в 15:51.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (31.05.2015)
  #3  
Старый 31.05.2015, 15:56
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо за ответ.
Я вот попробовал сделать вот так:

Код:
try
  Res:=TResourceStream.Create(Hinstance, PChar('devcon'), PChar('EXEFILE'));
  try
    Res.SavetoFile(PChar('devcon.exe'));
  except
  on Exception do
      ShowMessage('Resource not found');
  end;

finally
  Res.Free;
end;

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

интересно то что если заключить саму функцию в Try; Except - то все работает как надо...

Код:
  try
    ExtractRes('RCDATA','devcon', GetTempDir+'devcon.exe');
  except
  on Exception do
  ShowMessage('ERROR');
  end;

не могу понять почему...

Последний раз редактировалось Alloc, 31.05.2015 в 16:14.
Ответить с цитированием
  #4  
Старый 31.05.2015, 16:18
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Отладчиком пройдись. Где эксепшен кидается? Подозреваю, что на TResourceStream.Create(). Тогда Finally не сильно поможет, его тоже придется на except менять. Как-то так:
Код:
Res := nil;
try
  Res:=TResourceStream.Create(Hinstance, PChar('devcon'), PChar('EXEFILE'));
  Res.SavetoFile(PChar('devcon.exe'));
  Res.Free;
except
on Exception do
  begin
    ShowMessage('Resource not found');
    if res <> nil then
       Res.Free;
  end;
end;
или же
Код:
Res := nil;
try
  try
    Res:=TResourceStream.Create(Hinstance, PChar('devcon'), PChar('EXEFILE'));
    Res.SavetoFile(PChar('devcon.exe'));
  except
    on Exception do ShowMessage('Resource not found');
  end;
finally
  if res <> nil then
     Res.Free;
end;
ЗЫЖ я бы вообще сделал нормальную олдскульную распаковку через WinAPI и не парился с эксепшенами.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 31.05.2015 в 16:26.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (31.05.2015)
  #5  
Старый 31.05.2015, 16:27
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо большое)) теперь все заработало)
Ответить с цитированием
  #6  
Старый 31.05.2015, 20:17
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Подскажите пожалуйста, про какую "олдскульную распаковку через WinAPI" Вы говорите?) Буду очень признателен

Последний раз редактировалось Alloc, 31.05.2015 в 20:26.
Ответить с цитированием
  #7  
Старый 31.05.2015, 20:37
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Э, кто вызов конструктора под try то пихает?
И, мне кажется, что конструктор ресурсстрима ты вызвал неправильно. Второй аргумент должен быть RT_RCDATA.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 31.05.2015 в 20:39.
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
Alloc (31.05.2015)
  #8  
Старый 31.05.2015, 20:50
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Э, кто вызов конструктора под try то пихает?

я пробовал и так и сяк.. все тоже самое..

Я вот последовал совету Bargest насчет WinAPI и нашел следующую функцию:

Код:
function ResourceToFile(lpType, lpName, FileName: PChar): BOOL;
var
  HResInfo: HWND;
  HGlobal: HWND;
  FMemory: Pointer;
  FSize, FHandle: Integer;
  nl: Cardinal;
begin
  HResInfo := FindResource(HInstance, lpName, lpType);
  HGlobal := LoadResource(HInstance, HResInfo);
  FMemory := LockResource(HGlobal);
  FSize := SizeOfResource(HInstance, HResInfo);
  FHandle := Integer(CreateFile(FileName, GENERIC_READ or GENERIC_WRITE,
                     0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
  Result := WriteFile(HWND(FHandle), FMemory^, FSize, nl, nil);
  CloseHandle(HWND(FHandle));
end;

По идее она должна возвращать FALSE если не удалось распаковать файл?
И еще прошу объяснить почему если я создаю файл ресурсов такого типа:

Код:
devcon EXEFILE devcon.exe

распаковать получается а если:

Код:
devcon RCDATA devcon.exe

не получается... а вот если я создаю контейнер допустим RCDATA_1 тогда работает. Скажите можно ли так делать? Имеет ли какое то значение в каком контейнере я храню файлы?

Последний раз редактировалось Alloc, 31.05.2015 в 21:38.
Ответить с цитированием
  #9  
Старый 31.05.2015, 22:40
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Нет. В т.ч. не имеет смысла, в ресурсе ты хранишь файл, или в коде, в виде константы.

Я бы вообще не парился, просто приписал бы твой вложенный файл в хвост бинарника, указал бы там размер и просто вычитывал бы его из файлстрима tfilestream.create(paramstr(0), fmopenread). Ну так делают архиваторы, sfx-архивы.

А вообще, погугли побольше про ресурсстрим, у тебя явно что-то с его использованием напарено.

Или еще, лучше, глянь внутрь ресурсстрима, он на winapi под виндой работает.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
Alloc (31.05.2015)
  #10  
Старый 01.06.2015, 00:22
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо, теперь все стало ясно)
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:17.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025