» Программирование>Программа на делфи,самая малость осталась,тупик блин(((
AlexanderSergeev 20:41 13.03.2010
Вобщем написал программу,код которой не могу выложить.Смотрел много топиков по библиотекам и тп.Единственное к чему пришел,так это делать инсталлятор,но там такой гемор,но,если другого решения не найдется,придется только так(
Вобщем есть исполняемый файл (сама прога) и в той же папке еще два файла- (1)программа (ехе) и (2)библиотека (dll). Прога на делфи заносит нужные значения в реестр,создает несколько папок,затем запускает файл программы(1),ждет его завершения,выключается.проблема в том,что всю эту лабуду нужно свести к минимальному количеству файло,к одному.Причем это и должен быть файл моей проги (в нем все основное).А стороннюю программу,с её библиотекой, очень хотелось бы както запаковать чтоли в моё создание,чтобы дельфофская прога их разархивировала сама из себя,запустила,и даже можно чтобы удалила.
Но как запихать в прогу еще одну прогу стороннюю и библиотеку,я,к содалению,никак не могу понять.
Объясните хотя бы принцип,ссылки дайте,хоть как-то.Буду очень благодарен за помощь.
[Ответ]
Part!zan 20:50 13.03.2010
psihOZ, читай про ресурсы ехешников. Делается все очень просто. Создаешь ресурс с типом rcdata и пихаешь туда все, что угодно. Потом это все извлекаешь и делаешь свое дело. Надеюсь, ты не троян пишешь?
[Ответ]
Oldman 23:03 13.03.2010
Так что ты за программу пишешь? Уж очень описание смахивает на вирус или троян (или что-то в этом роде)! Я знаю решение, но без уверенности, что это не вирус, я не скажу его!
[Ответ]
X0R 23:34 13.03.2010
Писец. Ну вот скажет он что пишет блокнот, к которому могут подключаться модули - dll, от этого легче станет? Или это помешает автору применить освоенную технологию к вирусу?
[Ответ]
Yandex 00:11 14.03.2010
Параноики вы все
Мне кажется автору хочется безгемморно свою прогу распространять, т.е. даешь скопировать один exe и всё, больше ничего не надо (с виду). Бывает полезно, когда программу необходимо распространять среди людей далеких от компьютера.
Так же иногда требуется сныкать dll-ки, т.к. это чужая собственность.
[Ответ]
Part!zan 00:41 14.03.2010
Yandex, лучше перебдеть, чем недобдеть. Хотя, X0R прав, доказать злонамеренность невозможно.
[Ответ]
Ды нет,не вирус я пишу.просто моя програмка будет в самом конце запускать другую,стороннюю.вот и хочу впхнуть все в один файл,чтоб не папкой скидывать и не архивом.1 ехе.
вдруг с портэблом получится.
жду решений.
ЗЫ:спс за советы,пошел мучать поисковик)
[Ответ]
AlexanderSergeev 10:27 14.03.2010
вот что нашел ЗЫ:а как тут спойлеры делать? "+"<=>"-"
Заголовок ресурса выглядит следующим образом:
TResHeader = record
DataSize: DWORD; // размер данных
HeaderSize: DWORD; // размер этой записи
ResType: DWORD; // нижнее слово = $FFFF => ordinal
ResId: DWORD; // нижнее слово = $FFFF => ordinal
DataVersion: DWORD; // *
MemoryFlags: WORD;
LanguageId: WORD; // *
Version: DWORD; // *
Characteristics: DWORD; // *
end;
Поля помеченны звёздочкой Мы не будем использовать.
Приведённый код создаёт файл ресурсов и копирует его в данный файл:
procedure CreateResourceFile(
DataFile, ResFile: string; // имена файлов
ResID: Integer // id ресурсов
);
var
FS, RS: TFileStream;
FileHeader, ResHeader: TResHeader;
Padding: array [0..SizeOf(DWORD)-1] of Byte;
begin
{ Open input file and create resource file }
FS := TFileStream.Create( // для чтения данных из файла
DataFile, fmOpenRead);
RS := TFileStream.Create( // для записи файла ресурсов
ResFile, fmCreate);
{ Создаём заголовок файла ресурсов - все нули, за исключением
HeaderSize, ResType и ResID }
FillChar(FileHeader, SizeOf(FileHeader), #0);
FileHeader.HeaderSize := SizeOf(FileHeader);
FileHeader.ResId := $0000FFFF;
FileHeader.ResType := $0000FFFF;
{ Создаём заголовок данных для RC_DATA файла
Внимание: для создания более одного ресурса необходимо
повторить следующий процесс, используя каждый раз различные
ID ресурсов }
FillChar(ResHeader, SizeOf(ResHeader), #0);
ResHeader.HeaderSize := SizeOf(ResHeader);
// id ресурса - FFFF означает "не строка!"
ResHeader.ResId := $0000FFFF or (ResId shl 16);
// тип ресурса - RT_RCDATA (from Windows unit)
ResHeader.ResType := $0000FFFF
or (WORD(RT_RCDATA) shl 16);
// размер данных - есть размер файла
ResHeader.DataSize := FS.Size;
// Устанавливаем необходимые флаги памяти
ResHeader.MemoryFlags := $0030;
{ Записываем заголовки в файл ресурсов }
RS.WriteBuffer(FileHeader, sizeof(FileHeader));
RS.WriteBuffer(ResHeader, sizeof(ResHeader));
{ Копируем файл в ресурс }
RS.CopyFrom(FS, FS.Size);
{ Pad data out to DWORD boundary - any old
rubbish will do!}
if FS.Size mod SizeOf(DWORD) <> 0 then
RS.WriteBuffer(Padding, SizeOf(DWORD) -
FS.Size mod SizeOf(DWORD));
{ закрываем файлы }
FS.Free;
RS.Free;
end;
C процедурой я разобрался,а вот что делать с тем кодом.который красным выделил, вообще не понимаю...
[Ответ]
AlexanderSergeev 10:37 14.03.2010
И еще такой вопрос,у меня делфи (7) вместо button1 (edit2 и тп) пишет btn1 (edt2 и тп). тоесть какбы гласные пропадают чтоли.как эту фичу отключить?
[Ответ]
Yandex 10:46 14.03.2010
psihOZ, может пока не стоит пытаться прыгнуть выше головы и распространять программу вместе с dll?
После того, как ты разместил dll-в ресурсах физически ее извлекать не надо.
Сходи еще на форум sources.ru в раздел Delphi.
Взято с drkb.ru. Почему ты об этой базе знаний не знаешь, я без понятия.
Сообщение от : Хранение данных в EXE-файле
Вы можете включить любой тип данных как RCDATA или пользовательских тип ресурса. Это очень просто. Данный совет покажет вам общую технику создания такого ресурса.
Код:
Type
TStrItem = String[39]; { 39 символов + байт длины -> 40 байтов }
TDataArray = Array [0..7, 0..24] of TStrItem;
Const
Data: TDataArray = (
('..', ...., '..' ), { 25 строк на строку }
... { 8 таких строк }
('..', ...., '..' )); { 25 строк на строку }
Данные размещаются в вашем сегменте данных и занимают в нем 8K. Если это слишком много для вашего приложения, поместите реальные данные в ресурс RCDATA. Следующие шаги демонстрируют данный подход. Создайте небольшую безоконную программку, объявляющую типизированную константу как показано выше, и запишите результат в файл на локальный диск:
Код:
program MakeData;
type
TStrItem = string[39]; { 39 символов + байт длины -> 40 байтов }
TDataArray = array[0..7, 0..24] of TStrItem;
const
Data: TDataArray = (
('..', ...., '..'), { 25 строк на строку }
... { 8 таких строк }
('..', ...., '..')); { 25 строк на строку }
var
F: file of TDataArray;
begin
Assign(F, 'data.dat');
Rewrite(F);
Write(F, Data);
Close(F);
end.
Теперь подготовьте файл ресурса и назовите его DATA.RC. Он должен содержать только следующую строчку:
Код:
DATAARRAY RCDATA "data.dat"
Сохраните это, откройте сессию DOS, перейдите в каталог где вы сохранили data.rc (там же, где и data.dat!) и выполните следующую команду:
Код:
brcc data.rc (brcc32 для Delphi 2.0)
Теперь вы имеете файл data.res, который можете подключить к своему Delphi-проекту. Во время выполнения приложения вы можете генерировать указатель на данные этого ресурса и иметь к ним доступ, что и требовалось.
Код:
{ в секции interface модуля }
type
TStrItem = string[39]; { 39 символов + байт длины -> 40 байтов }
TDataArray = array[0..7, 0..24] of TStrItem;
PDataArray = ^TDataArray;
const
pData: PDataArray = nil; { в Delphi 2.0 используем Var }
implementation
{$R DATA.RES}
procedure LoadDataResource;
var
dHandle: THandle;
begin
{ pData := Nil; если pData - Var }
dHandle := FindResource(hInstance, 'DATAARRAY', RT_RCDATA);
if dHandle <> 0 then
begin
dhandle := LoadResource(hInstance, dHandle);
if dHandle <> 0 then
pData := LockResource(dHandle);
end;
if pData = nil then
{ неудача, получаем сообщение об ошибке с помощью
WinProcs.MessageBox, без помощи VCL, поскольку здесь код
выполняется как часть инициализации программы и VCL
возможно еще не инициализирован! }
end;
initialization
LoadDataResource;
end.
Теперь вы можете ссылаться на элементы массива с помощью синтаксиса pData^[i,j].
Автор: Peter Below
Yandex, вообще-то ему надо запихнуть 2 файла - ехешник и длл. длл требуется запихнутому ехешнику, так что, в любом случае, придется их извлекать.
Как-то все сложно в делфях... Неужто в IDE нельзя добавить желаемый ресурс в прогу, а не париться с самописными прогами и ком. строкой?
[Ответ]
AlexanderSergeev 13:04 14.03.2010
да извелкать надо будет.я как хочу сделать, с помощью всех этих процедур rcdata запакую в прогу мои файлы.а прога по нажатию кнопки будет их распаковывать в папку,запускать exe, ждать окончания и удалять эти файлы.думаю такое можно реализовать...
а что за IDE?прочитал что это среда разработки для приложений типа делфи,вижуала и си.но как и какую прогу мне в моем случае применить?
[Ответ]
Part!zan 13:07 14.03.2010
psihOZ, ну ты в чем программу-то пишешь? Не в блокноте же? Похоже, придется поставить себе эту делфи, чтобы глянуть, как там и чего...
[Ответ]
AlexanderSergeev 13:16 14.03.2010
ХДД) да делфи у меня я так понял самой полной версии стоит.я просто не так понял то,что было в википедии)
вобщем пошел думать с rcdata.
[Ответ]
Part!zan 13:36 14.03.2010
psihOZ, эта статья - слишком сложный вариант. Тебе не нужно на лету править ресурсы.
Нашел у себя в закромах делфи 6, посмотрел. Все очень заморочено там с созданием ресурсов.
Короче так... Создаешь файл чтонибудь.rc примерно такого вида
Если все сделано правильно, то должен появиться файл чтонибудь.res.
В свой unit1.pas (или как он у тебя называется) добавляешь строчку
Код:
{$R чтонибудь.res чтонибудь.rc}
И все. После компиляции в ресурсы ехешника будет добавлено 2 новых с именем exe и dll. Осталось только научиться их извлекать.
[Ответ]
AlexanderSergeev 14:34 14.03.2010
ура! добавились! СДЕЛАЛ ВСЕ ПОЧТИ КАК У ПАРТИЗАНА В #16 ОТВЕТЕ, только не через консоль,а прямо в делфи(borland resourse builder).вобщем теперь моя прога весит какраз почти как сумма всех 3х файлов!
теперь бы узнать как их извлечь... вот их процедура:
procedure ExtractToFile(Instance:THandle; ResID:Integer; ResType, FileName:string);
var
ResStream: TResourceStream;
FileStream: TFileStream;
begin
try
ResStream := TResourceStream.CreateFromID(Instance, ResID, pChar(ResType));
try
//if FileExists(FileName) then
//DeleteFile(pChar(FileName));
FileStream := TFileStream.Create(FileName, fmCreate);
try
FileStream.CopyFrom(ResStream, 0);
finally
FileStream.Free;
end;
finally
ResStream.Free;
end;
except
on E:Exception do
begin
DeleteFile(FileName);
raise;
end;
end;
end; а вот как я пытался применить её,но ничего не выходит:
procedure TForm1.btn1Click(Sender: TObject);
begin
ExtractToFile(HInstance;2;'CUSTOM';'11.exe');
-----------------
причем вместо HInstance я писал и application.handle и чтото еще вроде этого.в любом из вариантов почуму-то пишет (not enought actual...) параметров ей не хватает.что странно,все 4 вроде указываю.
----------------- Instance:THandle, что писать мне?
мдя...
[Ответ]
Part!zan 14:37 14.03.2010
Сообщение от psihOZ:
ExtractToFile(HInstance;2;'CUSTOM';'11.exe');
Я конечно, извиняюсь, но параметры всю жизнь через запятую отделялись.
[Ответ]
AlexanderSergeev 14:42 14.03.2010
блин,точно...хд...наверно на саму процедуру посмотрел,там-то через точкусзапятой... вобщем вот код: unit Unit1;
почему непонятно ошибка еще до кнопки выскакивает.что не так не знаю.
[Ответ]
Part!zan 15:02 14.03.2010
psihOZ, тип ресурса RCDATA должен быть, по идее. Да и почему ты решил, что идентификатор равен 2?
[Ответ]
Oldman 15:18 14.03.2010
Ладно, попробуй компонент MxStorage - прост и удобен в обращении!
[Ответ]
Part!zan 16:01 14.03.2010
psihOZ, для начала, почитай справку по TResourceStream.CreateFromID. А еще я малость напутал с rc файлом. Надо писать не "RCDATA exe", а "exe RCDATA"
Короче, че-то нифига с этим TResourceStream не получается. Пишет, что ресурс не найден, хотя он есть. Нужен кто-то более опытный в делфийских делах. Или сделать чтение ресурса способом, который Yandex предложил.
[Ответ]
Yandex 21:26 14.03.2010
Сообщение от :
вообще-то ему надо запихнуть 2 файла - ехешник и длл. длл требуется запихнутому ехешнику, так что, в любом случае, придется их извлекать.
Для решения такой вот задачи могу предложить вариант, описанный ниже. Разумеется у метода есть недостаток, что может и не удалить временные файлы.
Но это самый простой метод
Итак: пусть требуется извлекать программу test.exe и требуемый для ее работы файл test.txt. Пишем вот такой файл test.vbs (это скрипт на Windows Script Host)
Код:
Set objShell = WScript.CreateObject("WScript.Shell")
res = objShell.Run ("test.exe", 1, true)
Set fso = CreateObject("Scripting.FileSystemObject")
fso.DeleteFile ("test.exe")
fso.DeleteFile ("test.txt")
fso.DeleteFile ("test.vbs")
Этот скрипт при запускает test.exe и ждет его завершения. По завершению программы он удаляет test.exe, test.txt и себя.
А теперь финт ухами! Создаем в winrar sfx-архив, содержащий три файла exe, txt и vbs. Далее идем на вкладку "Дополнительно", там нажимаем на "Параметры SFX...".
В параметрах на вкладке "Общие" в "Выполнить после распаковки" пишем test.vbs, а на вкладке "Режимы" выбираем "Скрыть все" и "Переписывать все файлы без запроса".
Создаем архив.
Пример для тестирования во вложении.
Чтобы не пугались код test.exe
Код:
#include <iostream>
int main()
{
std::cout << "test.exe Press enter to continue.";
std::getchar();
return 0;
}
Yandex, это тривиальный способ. ) Можно в каком-нть инно инсталлере сделать то же самое даже более просто. Кстати, если мне не изменяет склероз, у rar есть собственный скриптовый язык для мини-инсталляторов. Там и стирать можно и все че угодно.
ЗЫ. Нефиговый у тебя хелловорлд получился по размеру )
[Ответ]
Yandex 22:23 14.03.2010
Part!zan,
Сообщение от :
Нефиговый у тебя хелловорлд получился по размеру )
Я старался
Перед отправкой заметил его размер - переделывать лень было через printf.
[Ответ]
DonPager 22:01 28.03.2010
...мдям psihOZ, для твоей задачи вообще ничего кроме блокнота не нужно - тупо всё это в самораспаковыющийся архив пихаешь и делаешь туда небольшой батник.
Этот батнег тебе и в реестр все данные напихает и удалит распакованые данные, правда след от выполнения этого варианта останется - вспомогательный батнег во временной папке, кототрый будет удалять 1й батнег...
[Ответ]
AlexanderSergeev 22:48 30.03.2010
ды епт...как в батнике прописать чтоб он тот самый архив,из которого его и разархивировали,еще в папку кидал?чтобы его еще раз запустить можно было?!
в том то все и дело,что пирамида какаято получается,матрешка епт.мне что,сто раз архив с батником сувать)...
вобщем стопорнулся Я на этом месте...потом чегонить придумаю...а пока и времени нет)
[Ответ]
DonPager 01:46 31.03.2010
вот как то так (требует доработки напильником):
main.cmd
Код:
echo del /y prog1.exe > %TMP%\1.cmd
echo del /y DLL.dll >> %TMP%\1.cmd
echo del /y params.reg >> %TMP%\1.cmd
echo del /y main.cmd >> %TMP%\1.cmd
start regedit params.reg
start prog1.exe /w
start %TMP%\1.cmd
можно ещё с SET позаморачиваться и попробовать удалять 1.cmd из мейна после запуска 1.cmd ,но нужны эксперименты...
[Ответ]
Yandex 19:07 31.03.2010
DonPager, месье знает толк в извращениях. cmd давно пора в топку.
Все то же самое на WSH без всяких ухищрений я привел выше.
WSH можно изучить за день, в степени достаточной для реализации простых задач.
[Ответ]