Сейчас на форуме: tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› Несколько файлов в одном модуле
Посл.ответ Сообщение

Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 22 марта 2008 05:13
· Личное сообщение · #1

Нужно после запуска вынуть из себя файлы и распихать по нужным дерикториям. Первое что приходит в голову это переменная с байтами файла. Но может есть проще способ? там не знаю, при компиляции добавить, или как то ещё? Может готовые куски кода есть? Джойнеры не предлагать.




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 22 марта 2008 07:17
· Личное сообщение · #2

Тебе надо засунуть файлы в секцию(секции) и потом записать это всё в файловую систему.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 22 марта 2008 09:14
· Личное сообщение · #3

Можно в ресурсы распихать, можно molebox накрыть.




Ранг: 748.2 (! !), 390thx
Активность: 0.370
Статус: Участник
bytecode!

Создано: 22 марта 2008 12:58 · Поправил: 4kusNick
· Личное сообщение · #4

Я для таких целей юзал ресурсы.

Писал на сях DLLку и юзал потом ее где попало.
Вот, например, код для вшивания в ресурсы чего-либо.


// ResDll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#define WINAPI __stdcall

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

bool WINAPI ReplaceResource(PCHAR sSource,PCHAR sDest,PCHAR sType,PCHAR sName)
{
// Переменные для чтения и добавления ресурса
HANDLE hFile;
DWORD dwFileSize,
dwBytesRead;
LPBYTE lpBuffer;

// Открываем файл для дальнейшего чтения
hFile = CreateFile(sSource,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NO RMAL,NULL);
// Если открыть не удалось, то выходим
if(hFile == INVALID_HANDLE_VALUE) return FALSE;
// Сохраняем его размер
dwFileSize = GetFileSize(hFile, NULL);
// Если не удалось получить размер, то выходим
if(dwFileSize <= NULL)
{
// Закрываем хендл файла
CloseHandle(hFile);
return FALSE;
}

// Создаём массив для чтения файла
lpBuffer = new BYTE[dwFileSize];

if (ReadFile(hFile,lpBuffer,dwFileSize,&dwBytesRead,NULL) != FALSE)
{
HANDLE hResource;

hResource = BeginUpdateResource(sDest,FALSE);
if (NULL != hResource)
{
if (UpdateResource(hResource,sType,sName,0,(LPVOID)lpBuffer,dwFileSize)!= FALSE)
{
EndUpdateResource(hResource, FALSE);
}
}
}
delete [] lpBuffer;
CloseHandle(hFile);
return true;
}



А вот пример того, как я юзал эту DLL из- под делфи (статика):


unit MainForm;

interface

uses
Windows, Messages; //...

type
//...
function ReplaceResource(sSource,sDest,sType,sName: PChar): Boolean; stdcall; external 'ResDll.dll';
//...

procedure //...
begin
//...
ReplaceResource(PChar(sTempPath + 'values.crt'),PChar(sTempPath + 'uninstall_exe.tmp'),RT_RCDATA,'VALUES');
//...




То же самое, только динамика:

unit MainFrm;

interface

uses
Windows; //...

type
TReplaceResource = function(sSource,sDest,sType,sName: PChar): Boolean; stdcall;
TMainForm = class(TForm)
//...


procedure TMainForm.PutSN(sPath: string);
var
ReplaceResource: TReplaceResource;
hndDLLHandle: THandle;
ReplaceResource: TReplaceResource;
MIn, MOut, MTmp: TMemoryStream;
hFile: TFileStream;
//...
begin

//...

// получаем адрес функции
@ReplaceResource := GetProcAddress(hndDLLHandle,'ReplaceResource');
// если адрес функции найден
if Addr(ReplaceResource) <> nil then
begin
ReplaceResource(PChar(sTempPath + '~dat~ap_.tmp'),PChar(sPath),RT_RCDATA,'DATAP');
end
else
ErrMsg(sShieldError,'0036',True);

//...

end;


Это все было по поводу запихивания в ресурсы...
А чтобы из себя распаковать, то можно делать так (2 варианта):
1. из себя:


function UnpackResFile(sResName: String; chResType: PAnsiChar; sSaveFileName: String = ''): TMemoryStream;
var
Fres: TResourceStream;

begin

try

Result := TMemoryStream.Create;

// помещаем файл из ресурсов в поток
Fres := TResourceStream.Create(0,sResName,chResType);
if FRes = nil then // проверяем, распаковался ли файл
begin
Result := nil;
Exit;
end;
Result.LoadFromStream(FRes);
if sSaveFileName <> '' then // если указан файл для сохранения, сохраняем
begin

ForceDirectories(ExtractFilePath(sSaveFileName));
Fres.SaveToFile(sSaveFileName);

end;
FRes.Free;
except
Result := nil;
end;

end;


2. из другого файла


function UnpackResFileFromFile(sFilePath,sResName: String; chResType: PAnsiChar; sSaveFileName: String = ''): TMemoryStream;
var
Fres: TResourceStream;
hFileHandle: Cardinal;
begin

Result := TMemoryStream.Create;
FRes := nil;

{Загружаем файл, как библиотеку}
hFileHandle := LoadLibrary(PChar(sFilePath));
if hFileHandle <> 0 then
// помещаем файл из ресурсов в поток
Fres := TResourceStream.Create(hFileHandle,sResName,chResType);
try
if FRes = nil then // проверяем, распаковался ли файл
begin
Result := nil;
Exit;
end;
Result.LoadFromStream(FRes);
if sSaveFileName <> '' then // если указан файл для сохранения, сохраняем
begin

ForceDirectories(ExtractFilePath(sSaveFileName));
Fres.SaveToFile(sSaveFileName);

end;
FRes.Free;
FreeLibrary(hFileHandle);
except
Result := nil;
end;
end;


-----
Флэш, ява, дотнет - на завтрак, обед и ужин. Unity3D на закуску.




Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 22 марта 2008 13:07
· Личное сообщение · #5

Хм, мне бы как нибудь так, что бы этот файл я при работе мог "распаковать" куда хочется.
Т.е. можно как-то так присоединить при компиляции, по извесному расположению, что бы потом обратится и записать в файл?



Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 22 марта 2008 14:02 · Поправил: tihiy_grom
· Личное сообщение · #6

Могу такой вариант предложить, правда на Delphi.

procedure unpackfile(path: string);
var
unpack_file: THandle;
begin
if not fileexists(path) then begin
unpack_file:= FileCreate(path);
FileWrite(unpack_file,data,sizeof(data));
FileClose(unpack_file);
end;
end;

Где data - это массив вида
data: array[0..5] of byte = ($4D, $5A, $50, $00, $02, $00);
ты его легко можешь получить в WinHex'e. Открываешь файл который тебе нужно будет потом копировать, и выбираешь CopyAll - Pascal Sources



Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 22 марта 2008 16:25
· Личное сообщение · #7

Ну я об этом в принципе и говорил, просто думал элегантнее способ есть.




Ранг: 120.9 (ветеран), 5thx
Активность: 0.080
Статус: Участник
Programmer and reverser

Создано: 22 марта 2008 16:35
· Личное сообщение · #8

Можно просто записать файлы в оверлей.

-----
Уважайте других и пишите грамотно.




Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 22 марта 2008 16:36
· Личное сообщение · #9

Я ничего более элегантного для себя не нашёл, этим и пользуюсь.
Ты объясни конкретнее что ты хочешь получить и на каком языке. И чем этот способ не устраивает?




Ранг: 279.1 (наставник)
Активность: 0.160
Статус: Участник
wizard

Создано: 22 марта 2008 16:41
· Личное сообщение · #10

Executioner пишет:
Можно просто записать файлы в оверлей.


а затем открыть программу в режиме чтения,считать с нужной позиции в буфер ,потом создаём пустой файл в нужной тебе директории и записываем в него данные из буфера.

-----
Что один человек сделал , другой всегда сломать может...



 eXeL@B —› Программирование —› Несколько файлов в одном модуле
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати