![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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; Последний раз редактировалось 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;Последний раз редактировалось Bargest, 31.05.2015 в 16:26. |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Alloc (31.05.2015)
| ||
|
#5
|
||||
|
||||
|
Спасибо большое)) теперь все заработало)
|
|
#6
|
||||
|
||||
|
Подскажите пожалуйста, про какую "олдскульную распаковку через WinAPI" Вы говорите?) Буду очень признателен
Последний раз редактировалось Alloc, 31.05.2015 в 20:26. |
|
#7
|
||||
|
||||
|
Э, кто вызов конструктора под try то пихает?
И, мне кажется, что конструктор ресурсстрима ты вызвал неправильно. Второй аргумент должен быть RT_RCDATA. Последний раз редактировалось 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 под виндой работает. |
| Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
Alloc (31.05.2015)
| ||
|
#10
|
||||
|
||||
|
Спасибо, теперь все стало ясно)
|