PDA

View Full Version : اضافه کردن فایل به فایل EXE



ali_mohamadi8928
دوشنبه 17 دی 1386, 01:48 صبح
سلام .

دوستان چطوری میشه یک فایل رو به یک فایل exe که خودمون با دلفی نوشتیم اظافه کنیم .

البته این کار قبل از کامپایل با اظافه کردن ریسورس به راحتی امکان پذیر هستش .

حالا من میخوام بدونم چه جوری با کد نویسی میشه این کار رو کرد ؟

البته این کار با نرم افزارهایی همچون Restorator هم خیلی راحت هستش . که من از مراحل اظافه کردن فایل توسط این نرم افزار فیلم گرفتم و براتون میزارم تا منظورم رو بهتر متوجه بشین .

ali_mohamadi8928
دوشنبه 17 دی 1386, 23:17 عصر
دوستان ایا این کار با دلفی امکان پذیر هست یا نه ؟

اگه ممکن هست لطفا یک راهنمایی جامع بکنید .

با تشکر ...

vcldeveloper
سه شنبه 18 دی 1386, 02:57 صبح
قبلا بحث شده.

seyed_farid
سه شنبه 18 دی 1386, 23:51 عصر
کاش دوستان بجای نوشتن جمله "قبلا بحث شده" و " یه سرچ بزن" و " ... " فقط با یه لینک راهنما میشدند.

vcldeveloper
چهارشنبه 19 دی 1386, 03:29 صبح
کاش دوستان بجای نوشتن جمله "قبلا بحث شده" و " یه سرچ بزن" و " ... " فقط با یه لینک راهنما میشدند.
شرمنده، همه اونقدر وقت ندارند که کل این سایت را بگردند و لینکی مناسب سوال شما پیدا کنند. اگر مطلبی بود که حضور ذهن داشتم، یا بالافاصله یه Keyword مرتبط با اون مطلب به ذهنم می رسید، بهتون لینک می دادم. اما چون فرصت جستجو نداشتم و از طرفی کاملا مطمئن هم هستم که بارها این مطلب در این سایت بحث شده، گفتم جستجو کنید.
علت قفل نکردن تاپیک هم این بود که یکی از دوستان که حضور ذهن داره، یا فرصت جستجو داره، لینکی به یکی از تاپیک های مرتبط با این موضوع اینجا بزاره، وگرنه بر طبق قانون سایت باید این تاپیک قفل یا حذف می شد!

ali_mohamadi8928
چهارشنبه 19 دی 1386, 20:32 عصر
سلام دوستان .

من که گشتم و چیزی پیدا نکردم .

یکی از دوستان اگه بتونن لینک تاپیک های بحث شده یا یک مثال بزارن خیلی ممنون میشم .

با تشکر ....

Delphi Coder
پنج شنبه 20 دی 1386, 10:19 صبح
با همون اضافه کردن Resource میشه اینکارو کرد. XN Resource Editor (http://www.wilsonc.demon.co.uk/d10resourceeditor.htm) یه Resource Editor که با زبان دلفی نوشته شده و OpenSource هم هست. به احتمال قوی سورس این برنامه کمکتون میکنه.

seyed_farid
جمعه 21 دی 1386, 10:36 صبح
من اینو تو سایت دیدم ، ولی فقط کارش نوشتن تو فایل اجرائی است و تو خودش هم نمیتونه بنویسه وقتی تو اجراست.
http://barnamenevis.org/forum/showpost.php?p=353418&postcount=150

ali_mohamadi8928
شنبه 22 دی 1386, 07:48 صبح
این رو خودم داشتم ولی به درد این کار نمیخوره .

اون برنامه ای که دوستمون هم گذاشت باز به کارم نیومد . چون با دلفی 2006 بود .

من از دلفی 7 استفاده میکنم .

با تشکر ....

Delphi Coder
شنبه 22 دی 1386, 08:03 صبح
باید بگم این کار ساده ای نیست که بتونید با یکی دو تا دستور انجام بدید باید کد بنویسید و برای اینکار باید به ساختار فایل PE آشنایی کامل داشته باشید. اون برنامه OpenSource رو خیلی قشنگ پیاده سازی کردن نعمت به اون بزرگی در اختیارتون هست. مطمئن باشید خیلی کمکتون میکنه حداقل چند تا کلاسای اونو میتونید استفاده کنید.
البته شاید هم برای محک زدن خودتون بخواید از ب بسم ا..ه خودتون بنویسید. :گیج:
Good Luck

Valadi
شنبه 22 دی 1386, 08:38 صبح
اینو ببنید

Reference:

bool : csi_fat_available
bool : csi_fat_get_file_list(files:tstringlist)
cardinal : cis_load_file(fn:string;p:pointer)
bool : cis_save_file(fn:string)
bool : cis_delete_file(fn:string)
bool : cis_file_exists(fn:string)

CIS-FAT - Code: [Cybergen Internal Small - File Allocation Table]
}

(* CSI-FAT - START *)

function RunProg(Cmd, WorkDir: string): string;
var
tsi: TStartupInfo;
tpi: TProcessInformation;
nRead: DWORD;
aBuf: array[0..101] of Char;
sa: TSecurityAttributes;
hOutputReadTmp, hOutputRead, hOutputWrite, hInputWriteTmp, hInputRead,
hInputWrite, hErrorWrite: THandle;
FOutput: string;
begin
FOutput := '';

sa.nLength := SizeOf(TSecurityAttributes);
sa.lpSecurityDescriptor := nil;
sa.bInheritHandle := True;

CreatePipe(hOutputReadTmp, hOutputWrite, @sa, 0);
DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(),
@hErrorWrite, 0, True, DUPLICATE_SAME_ACCESS);
CreatePipe(hInputRead, hInputWriteTmp, @sa, 0);

// Create new output read handle and the input write handle. Set
// the inheritance properties to FALSE. Otherwise, the child inherits
// the these handles; resulting in non-closeable handles to the pipes
// being created.
DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(),
@hOutputRead, 0, False, DUPLICATE_SAME_ACCESS);
DuplicateHandle(GetCurrentProcess(), hInputWriteTmp, GetCurrentProcess(),
@hInputWrite, 0, False, DUPLICATE_SAME_ACCESS);
CloseHandle(hOutputReadTmp);
CloseHandle(hInputWriteTmp);

FillChar(tsi, SizeOf(TStartupInfo), 0);
tsi.cb := SizeOf(TStartupInfo);
tsi.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
tsi.hStdInput := hInputRead;
tsi.hStdOutput := hOutputWrite;
tsi.hStdError := hErrorWrite;

CreateProcess(nil, PChar(Cmd), @sa, @sa, True, 0, nil, PChar(WorkDir),
tsi, tpi);
CloseHandle(hOutputWrite);
CloseHandle(hInputRead);
CloseHandle(hErrorWrite);
Application.ProcessMessages;

repeat
if (not ReadFile(hOutputRead, aBuf, 16, nRead, nil)) or (nRead = 0) then
begin
if GetLastError = ERROR_BROKEN_PIPE then Break
else
MessageDlg('Pipe read error, could not execute file', mtError, [mbOK], 0);
end;
aBuf[nRead] := #0;
FOutput := FOutput + PChar(@aBuf[0]);
Application.ProcessMessages;
until False;

Result := FOutput;
//GetExitCodeProcess(tpi.hProcess, nRead) = True;
end;

type
PImageDosHeader = ^TImageDosHeader;
TImageDosHeader = packed record
e_magic: Word;
e_ignore: packed array[0..28] of Word;
_lfanew: Longint;
end;

function GetExeSize: Cardinal;
var
p: PChar;
i, NumSections: Integer;
begin
Result := 0;
p := Pointer(hinstance);
Inc(p, PImageDosHeader(p)._lfanew + SizeOf(DWORD));
NumSections := PImageFileHeader(p).NumberOfSections;
Inc(p, SizeOf(TImageFileHeader) + SizeOf(TImageOptionalHeader));
for i := 1 to NumSections do
begin
with PImageSectionHeader(p)^ do
if PointerToRawData + SizeOfRawData > Result then
Result := PointerToRawData + SizeOfRawData;
Inc(p, SizeOf(TImageSectionHeader));
end;
end;

function csi_fat_available: Boolean;
var
f: file;
head: Word;
nr: Integer;
begin
Result := False;
filemode := 0;
assignfile(f, ParamStr(0));
reset(f, 1);
head := 0;
if filesize(f) = getexesize then
begin
closefile(f);
Exit;
end;
seek(f, getexesize);
blockread(f, head, 2,nr);
if (head = $12FE) and (nr = 2) then Result := True;
closefile(f);
filemode := 2;
end;

function csi_fat_get_file_list(var files: TStringList): Boolean;
type
tfileentry = record
FileName: string[255];
filesize: Cardinal;
end;
var
f: file;
i, num, head: Word;
nr: Integer;
tfe: tfileentry;
begin
Result := False;
filemode := 0;
assignfile(f, ParamStr(0));
reset(f, 1);
seek(f, getexesize);
blockread(f, head, 2,nr);
if not ((head = $12FE) and (nr = 2)) then
begin
Result := False;
closefile(f);
Exit;
end;
blockread(f, num, 2,nr);
if (nr <> 2) then
begin
Result := False;
closefile(f);
Exit;
end;
for i := 1 to num do
begin
blockread(f, tfe, SizeOf(tfe), nr);
if nr <> SizeOf(tfe) then
begin
Result := False;
closefile(f);
Exit;
end;
files.Add(tfe.FileName);
end;
closefile(f);
filemode := 2;
Result := True;
end;

function cis_load_file(fn: string; var p: Pointer): Cardinal;
type
tfileentry = record
FileName: string[255];
filesize: Cardinal;
end;
var
f: file;
i, num, head: Word;
nr: Longint;
tfe: tfileentry;
fofs: Cardinal;
begin
Result := 0;
filemode := 0;
assignfile(f, ParamStr(0));
reset(f, 1);
fofs := getexesize;
seek(f, fofs);
blockread(f, head, 2,nr);
Inc(fofs, 2);
if not ((head = $12FE) and (nr = 2)) then
begin
Result := 0;
closefile(f);
Exit;
end;
blockread(f, num, 2,nr);
Inc(fofs, 2);
if (nr <> 2) then
begin
Result := 0;
closefile(f);
Exit;
end;
for i := 1 to num do
begin
blockread(f, tfe, SizeOf(tfe), nr);
Inc(fofs, SizeOf(tfe));
if nr <> SizeOf(tfe) then
begin
Result := 0;
closefile(f);
Exit;
end;
if (lowercase(tfe.FileName) = lowercase(fn)) then
begin
seek(f, fofs);
getmem(p, tfe.filesize);
blockread(f, p^, tfe.filesize, nr);
if (nr <> tfe.filesize) then
begin
ShowMessage('Unable to Load whole file');
freemem(p, tfe.filesize);
Result := tfe.filesize;
filemode := 2;
Exit;
end;
Result := tfe.filesize;
closefile(f);
ShowMessage('Loaded');
filemode := 2;
Exit;
end;
Inc(fofs, tfe.filesize);
end;
closefile(f);
// file nicht im CIS
ShowMessage('File not in CIS loading Orig. Destination');
assignfile(f, fn);
reset(f, 1);
getmem(p, tfe.filesize);
blockread(f, p^, filesize(f));
closefile(f);
filemode := 2;
Result := 0;
end;

function cis_file_exists(fn: string): Boolean;
var
files: TStringList;
i: Word;
begin
Result := False;
files := TStringList.Create;
csi_fat_get_file_list(files);
for i := 1 to files.Count do
if i <= files.Count then
if lowercase(files[i - 1]) = lowercase(fn) then Result := True;
files.Free;
end;

procedure FileCopy(const sourcefilename, targetfilename: string);
var
S, T: TFileStream;
begin
filemode := 2;
S := TFileStream.Create(sourcefilename, fmOpenRead);
try
T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate);
try
T.CopyFrom(S, S.Size);
finally
T.Free;
end;
finally
S.Free;
end;
end;

function randname: string;
var
i: Integer;
s: string;
begin
Randomize;
s := '';
for i := 1 to 20 do s := s + chr(Ord('a') + Random(26));
Result := s;
end;

procedure _filecopy(von, nach: string);
var
f: file;
c, cmd: string;
begin
filemode := 2;
ShowMessage(von + ' -> ' + nach);
cmd := 'cmd';
if fileexists('cmd.exe') then cmd := 'cmd';
if fileexists('c:\command.com') then cmd := 'command.com';
c := 'ren ' + nach + ' ' + randname;
runprog(cmd + ' /c ' + c, GetCurrentDir);
assignfile(f, von);
rename(f, nach);
end;

function cis_delete_file(fn: string): Boolean;
type
tfileentry = record
FileName: string[255];
filesize: Cardinal;
end;
var
f, o: file;
nrr, nr: Integer;
exes: Longint;
j, i, num, w: Word;
tfe: tfileentry;
tfel: array[1..$ff] of tfileentry;
p: Pointer;
begin
if not cis_file_exists(fn) then
begin
Result := False;
Exit;
end;
assignfile(f, ParamStr(0));
reset(f, 1);
assignfile(o, ParamStr(0) + '.tmp');
rewrite(o, 1);
exes := getexesize;
// nur die exe kopieren
getmem(p, exes);
blockread(f, p^, exes);
blockwrite(o, p^, exes);
freemem(p, exes);
blockread(f, w, 2);
blockread(f, num, 2);
Dec(num);
// cis-header schreiben
w := $12FE;
blockwrite(o, w, 2);
blockwrite(o, num, 2);
// jetzt alle files au?er "fn" kopieren
// aber erst die FAT
fillchar(tfel, SizeOf(tfel), 0);
for i := 1 to num + 1 do
begin
blockread(f, tfe, SizeOf(tfe));
move(tfe, tfel[i], SizeOf(tfe));
if lowercase(tfe.FileName) <> lowercase(fn) then blockwrite(o, tfe, SizeOf(tfe));
end;
// jetzt noch die file daten einkopieren
for i := 1 to num + 1 do
begin
getmem(p, tfel[i].filesize);
blockread(f, p^, tfel[i].filesize);
if lowercase(tfe.FileName) <> lowercase(fn) then // copy block
blockwrite(o, p^, tfel[i].filesize);
freemem(p, tfel[i].filesize);
end;
closefile(f);
closefile(o);
_filecopy(ParamStr(0) + '.tmp', ParamStr(0));
end;

function cis_append_file(fn: string): Boolean;
type
tfileentry = record
FileName: string[255];
filesize: Cardinal;
end;
var
f, o, s: file;
exes: Longint;
p: Pointer;
i, w, num: Word;
tfe: tfileentry;
fs: Cardinal;
nwr: Cardinal;
begin
assignfile(f, ParamStr(0));
reset(f, 1);
assignfile(o, ParamStr(0) + '.tmp');
rewrite(o, 1);
exes := getexesize;
if not csi_fat_available then
begin
// create cis
getmem(p, exes);
blockread(f, p^, exes);
blockwrite(o, p^, exes);
freemem(p, exes);
// create fat-header
w := $12FE;
blockwrite(o, w, 2);
num := 1;
blockwrite(o, num, 2);
tfe.FileName := fn;
// copy file
assignfile(s, fn);
reset(s, 1);
tfe.filesize := filesize(s);
getmem(p, filesize(s));
blockwrite(o, tfe, SizeOf(tfe));
blockread(s, p^, filesize(s));
blockwrite(o, p^, filesize(s));
freemem(p, filesize(s));
closefile(s);
closefile(f);
closefile(o);
_filecopy(ParamStr(0) + '.tmp', ParamStr(0));
Result := True;
Exit;
end;
// nur die exe kopieren
getmem(p, exes);
blockread(f, p^, exes);
blockwrite(o, p^, exes);
freemem(p, exes);
blockread(f, w, 2);
blockread(f, num, 2);
Inc(num);
// cis-header schreiben
w := $12FE;
blockwrite(o, w, 2);
blockwrite(o, num, 2);
// copy all file entrys
for i := 1 to num - 1 do
begin
blockread(f, tfe, SizeOf(tfe));
blockwrite(o, tfe, SizeOf(tfe));
end;
tfe.FileName := fn;
assignfile(s, fn);
reset(s, 1);
tfe.filesize := filesize(s);
blockwrite(o, tfe, SizeOf(tfe));
fs := filesize(f);
getmem(p, fs);
blockread(f, p^, fs, nwr);
blockwrite(o, p^, nwr);
freemem(p, fs);
getmem(p, fs);
blockread(f, p^, fs);
blockwrite(o, p^, fs);
freemem(p, fs);
closefile(f);
closefile(o);
_filecopy(ParamStr(0) + '.tmp', ParamStr(0));
Result := True;
end;

function cis_save_file(fn: string): Boolean;
begin
if not cis_file_exists(fn) then cis_append_file(fn)
else
begin
cis_delete_file(fn);
cis_save_file(fn);
end;
end;

(* CSI-FAT - STOP *)

// -------------- Howto Use: -----------------------------------------

// ... some code ...
// if file is not in the VFS load it into ..
if not cis_file_exists('e:\xm\shold.xm') then cis_save_file('e:\xm\shold.xm');
// Load File
cis_load_file('e:\xm\shold.xm', muke);
// ... some code ...
play(muke);


{+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++
What it does and how it does:

The CIS-FAT-System binds File of any Kind at the
End of an Executable (EXE-Binder) but it also
have a nice File-Table and you can "Dynamically"
save, delete & load Files.

It is possible for example to Code the Binary
with all single Files external ...
After a Little Check you can modifiy your code that way
that the CIS-FAT on First Start automatically load all nesseary
Files into the Binary-FS.

So can add Music, Movies, Images ... all in one Big-File.

The best is that you can use Static-Filenames!
For example:

// This Line loads an External File into the Binary if its not already in it.
if not cis_file_exists('e:\xm\shold.xm') then cis_save_file('e:\xm\shold.xm');

// This Line access the File in the Binary, if its not in it uses the
// External Version of the File.
cis_load_file('e:\xm\shold.xm',muke);

So there is no need to change Filenames.



ضمنا 3 کامپونت هم در این زمینه هست یکی از انها آقای کبیری در سایت قرار داده است

ali_mohamadi8928
شنبه 22 دی 1386, 11:03 صبح
متاسفانه ایشون رو نمیشناسم .

میشه لینکش رو بزارید ؟

ممنون

Valadi
شنبه 22 دی 1386, 11:14 صبح
من کامپونت آقای کبیری را دارم اما در سیستم گم کردم (ضمنا این کامپونت 5 تا فایل را داخل فایل اجرایی می برد و خودش هم این کامپونت نوشته بود)


کامپونت دوم به نام Virtual Stream
در سایت www.ksdev.com
این کامپونت می تونی n تا فایل وارد یک فایل کنی و با یک پسوند خاص
ضمنا این شبیه کامپونت آقای سالار خلیل زاد هم نوشته و رایگانه و می تونه استفاده کنی



کامپونت سوم :FileStorage
در سایت http://www.appcontrols.com/components.html


The FileStorage component capable to upload and hold any data files within your Delphi/BCB forms (within the body of the EXE-program).
If your software requires any additional files (.DLL's, WAV's, .TXT's etc), these files could be uploaded straight onto your form and be extracted from executable file at run-time. Also you can access to stored files directly from memory without extracting them to disk.
With FileStorage you can supply your customers with just one executable file!
Package contains bonus component, WavPlayer, which able to upload Wave sounds onto your forms and play them at run-time.

شما می تونید از کامپونت سومی استفاده کنی توضیح هش که قرار دادم

ali_mohamadi8928
شنبه 22 دی 1386, 11:17 صبح
اقای Valadi به خاطر این کد خیلی ممنونم.

من نتونستم درست ازش استفاده کنم .

اگه میشه لطف کنید و خودتون یک نمونه با این کد درست کنید و اینجا برای دانلود بزارید .
( اخه خیلی بهش نیاز دارم )

یک دنیا ممنون میشم .

Valadi
شنبه 22 دی 1386, 11:42 صبح
یک راه ساده این که از ریسورس استفاده کنی

ali_mohamadi8928
شنبه 22 دی 1386, 11:49 صبح
یک راه ساده این که از ریسورس استفاده کنی

مگه برای فایل exe هم میشه از ریسورس استفاده کرد ؟؟؟ :متعجب:

چه جوری اخه ؟؟ :متفکر:

ali_mohamadi8928
شنبه 22 دی 1386, 13:41 عصر
والا هیچ کدوم از کامپونت هایی که معرفی کردین رایگان نبودن .

اگه یکی ازدوستان کامپونت اقای کبیری رو بزاره خیلی ممنون میشم .

Valadi
شنبه 22 دی 1386, 14:52 عصر
بله همه کامپونتها رایگان نیستند یا ....
کامپونت دومی در سایت آقای سالار خلیل زاد هست
ایمیل تان ؟؟؟ تا براتون ارسال کنم البته کامپونت آقای کبیری را پیدا کردم

ali_mohamadi8928
شنبه 22 دی 1386, 15:13 عصر
اگه میبشه لطف کنید و به صورت پیام خصوصی توی همین سایت برام بفرستین .

در ضمن یک فکری به ذهن خودم رسید که یه چیزی این وسط کم دارم برای حل مسئله .

یک متغییر میخوام که بتونه فایل رو توی خودش نگه داری بکنه و بدون اینکه کپی بکنه توی هارد بتونه فایل رو اجرا بکنه .

و قابلیت کپی کردن فایلی که توش هست رو به هارد داشته باشه .

ایا همچین متغییری هستش ؟؟؟

اگه وجود داره لطفا معرفی کنید و روش کار کردن باهاش رو یکمی توضیح بدید .

با تشکر از اقای ولدی ...

Valadi
شنبه 22 دی 1386, 16:21 عصر
در فایل های فلش چنین کاری میشه کرد بدون هیچ فایل temp این کار میشه کرد درمورد فایل دیگه هنوز مشکل دارم
ایمیل بدید فقط از طریق ایمیل

یک متغییر میخوام که بتونه فایل رو توی خودش نگه داری بکنه

کامپونت دوم این کار میکنه

Valadi
شنبه 22 دی 1386, 17:44 عصر
فایل ارسال شد امیدوارم مشکلتون حل بشه

gbg
دوشنبه 24 دی 1386, 22:30 عصر
سلام
من این کامپوننت رو نوشتم ولی بخاطر بی مهری بعضی از دوستان ادامه ندادم فکر می کنم تو این لینک بود
http://barnamenevis.org/forum/showthread.php?t=45609

vcldeveloper
سه شنبه 25 دی 1386, 04:25 صبح
این مقاله شاید بهتون کمک کنه:

lord_viper
چهارشنبه 26 دی 1386, 09:15 صبح
اینم مقاله خوبیه و در مورد قرار دادن کد برنامه داخل exe های دیگه هست که با اجرای انها کد برنامه ای که داخلش هست هم اجرا میشه(این دقیقا اموزش روشیه که ویروس جیفو برای چسباندن خودش به exe ازش استفاده میکنه)