![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() Здравствуйте!
Научите пожалуйста как правильно организовать исключения на примере следующей функции: Код:
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
|
||||
|
||||
![]() Если дело в эксепшене, то наверное как-то так.
Код:
try // unpack code Res.Free; except Res.Free; Result := false; end; jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 31.05.2015 в 15:51. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Alloc (31.05.2015)
|
#3
|
||||
|
||||
![]() Спасибо за ответ.
Я вот попробовал сделать вот так: Код:
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
|
||||
|
||||
![]() Отладчиком пройдись. Где эксепшен кидается? Подозреваю, что на 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; jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 31.05.2015 в 16:26. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Alloc (31.05.2015)
|
#5
|
||||
|
||||
![]() Спасибо большое)) теперь все заработало)
|
#6
|
||||
|
||||
![]() Подскажите пожалуйста, про какую "олдскульную распаковку через WinAPI" Вы говорите?) Буду очень признателен
Последний раз редактировалось Alloc, 31.05.2015 в 20:26. |
#7
|
||||
|
||||
![]() Э, кто вызов конструктора под 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
|
||||
|
||||
![]() Цитата:
я пробовал и так и сяк.. все тоже самое.. Я вот последовал совету 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
|
||||
|
||||
![]() Нет. В т.ч. не имеет смысла, в ресурсе ты хранишь файл, или в коде, в виде константы.
Я бы вообще не парился, просто приписал бы твой вложенный файл в хвост бинарника, указал бы там размер и просто вычитывал бы его из файлстрима tfilestream.create(paramstr(0), fmopenread). Ну так делают архиваторы, sfx-архивы. А вообще, погугли побольше про ресурсстрим, у тебя явно что-то с его использованием напарено. Или еще, лучше, глянь внутрь ресурсстрима, он на winapi под виндой работает. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
Alloc (31.05.2015)
|
#10
|
||||
|
||||
![]() Спасибо, теперь все стало ясно)
|