![]() |
INI in EXE einbinden
Hi @ all
Ich weiß das meine Überschrift nicht gerade gut ist , denn ich meine nicht wie man eine EXE dazu bringt daten aus einer INI zu verwenden sondern : Ich will wissen ob es möglich ist an eine EXE datei eine INI anhängen kann die beim Ausführen der EXE erst in ein bestimmten Ordner installiert wird . So soll das ganse funktionieren : Mein Hauptprogramm heist z.B Start.exe und ist in einem Ordner ( egal welchem ) . Die Start.exe ist darauf angewiesen bestimmte Daten aus einer INI datei zu lesen . Im Selben Ordner soll sich eine art Editor befinden . Den Öffnet man und kann gans leicht seine Angaben machen die in die INI geschrieben werden . Wenn man nun im Editor auf Fertig stellen drückt soll die INI datei in die Start.exe eingefügt werden . Wenn die Start.exe nun ausgeführt wird , soll dann wie gesagt die INI in einen bestimten Ordner entpackt werden . Leider habe ich keinen schimmer von solchen vorgängen und hoffe Unterstützung . Danke |
Re: INI in EXE einbinden
wie Wäre es mit
Delphi-Quellcode:
oder nich?
ST:=TStringList.Create;
ST.Add('[Dings]'); ST.Add('Achso = 1'); ST.Add('[Brummli]'); ST.Add('DingensDa = 2'); ST.Add('UnUeberhauptUndSo = Sodele'); ST.Add('Letztes = Allerletzes'); ST.SaveToFile('Folder/File.ini'); Edit(Vergessen): Das ganze in Verbindung mit nem TFileStream der die entsprechenden Stellen ersetzt... dass müsste man halt mit höchstgrenzen für die StringLänge machen, sodass der Rest mit Leerzeichen gefüllt wird, die im Add-Aufruf mit nem Statischen Trim() wieder gekillt werden könnten.... |
Re: INI in EXE einbinden
Ich weiß wie man eine INI erstellt nur will ich wissen wie man sie an eine EXE Binde und dafür sorgt das wenn die EXE ausgeführt wird dir INI mit ihren gansen inhalt der schon bearbeitet wurde in einen Ordner entpackt und von der EXE benutzt werden kan.
|
Re: INI in EXE einbinden
ja so:
(im OnCreate oder so aufrufen...)
Delphi-Quellcode:
wobei das was halt innerhalb der Trunc() steht geändert werden müsste
procedure CreateIni;
var SL: TStringList; begin SL:=TStringList.Create; SL.Add(Trunc('[Dings] ')); SL.Add(Trunc('Achso = 1 ')); SL.Add(Trunc('[Brummli] ')); SL.Add(Trunc('DingensDa = 2 ')); SL.Add(Trunc('UnUeberhauptUndSo = Sodele')); SL.Add(Trunc('Letztes = Allerletzes ')); SL.SaveToFile('Folder/File.ini'); SL.Free; end; das Ändern: ![]() |
Re: INI in EXE einbinden
Zitat:
glkgereon hat doch so einen Weg gezeigt. Das ganze dann ins Oncreate des Forms (bzw. wahlweise auch in die Projektdatei) schreiben und die Exe starten ;) |
Re: INI in EXE einbinden
Was soll denn das ? Entweder wird was fest eincompiliert in die EXE, oder es kommt sonstwo hin, z.B. INI. Es geht nur darum EBEN NICHTS an der Exe zu ändern !! Genau das willst du aber machen. Wenn jetzt jemand eine Fehlermeldung angibt, dann kannst du es eventuell nicht mal mehr genau lokalisieren, sofern an der EXE rumgefummelt wurde. Also : Wozu soll das gut sein ?
|
Re: INI in EXE einbinden
damit wollte ich einstellungen an der fertigen exe vornehmen ohne stark in den eigendlichen source ein zu greifen
|
Re: INI in EXE einbinden
So macht man das aber nicht ! Dafür sind doch INIs usw. da. Es ist viel einfacher eine Ini zu verändern, die von einer EXE ausgelesen wird, als die EXE zu verbiegen. 8) Natürlich muß der Source in der Lage sein, die INI richtig zu verarbeiten. Notfalls EXE+INI neu ausliefern. Zumindest nicht ein Programm, das eine vorhandene EXE vergewaltigt.
|
Re: INI in EXE einbinden
wieso Hansa?
man müsste Halt nur versuchen für den IniTeil den String vorerst eindeutig zu machen...zum finden. Genau hier sehe auch ich dass Problem: dass man eben NIE mit 100%iger Sicherheit sagen kann: Dieser String kommt hier, und NUR hier vor in der exe...man kann also nie ganz ausschließen dass man ausversehen ein stückchen "code" verhackstückt. Ist der String richtig gewählt sollte dieses Problem imho jedoch praktisch ausgeschlossen sein... |
Re: INI in EXE einbinden
Zitat:
|
Re: INI in EXE einbinden
nö, so in etwa...(achtung, jetzt so spontan nach 1 Woche PC-Entzug *zitter* *sabber* ;) )
guckt ma drüber ob die ganzen namen so stimmen...aber das grundkonzept sollte gehen. wie gesagt, es KANN schiefgehen. aber je höher Max ist, desto
Delphi-Quellcode:
const
Max: Integer = 20; //Länge der Strings function Fill(Val:String):String; var i:Integer; begin for i:=1 to Max-Length(Val) do Result:=Result+' '; Result:=Val+Result; end; procedure ReplaceIniInExe(Rep, RepWith: TStringList); var FS: TFileStream; Buf: String[Max]; begin FS:=TFileStream.Create('Bla.Exe',fmShareExclusive or fmReadWrite); while FS.Position<FS.Size do begin FS.Read(Buf,Max); if Rep.IndexOf(Trim(Buf))>-1 then begin FS.Position:=FS.Position-Max; FS.Write(Fill(RepWith.Strings[Rep.IndexOf(Trim(Bux))])); end; end; FS.Free; end; |
Re: INI in EXE einbinden
Du kannst die Daten an die Exe anhängen (zum Beispiel mit einem TMemoryStream).
Den Start der anghängten Daten kann man zur Laufzeit anhand des PE/COFF-Headers aus dem Image auslesen. (so funktioniert das auch bei etlichen selbsextrahierenden Programmen) Einfacher Weg die Ini an die Exe anzuhängen:
Code:
Und zur Laufzeit an die Daten kommen:
copy /B Project1.exe + /B Foo.ini Project1Foo.exe
Delphi-Quellcode:
unit PE32Stub {platform};
interface function GetOverlay(var Buffer: Pointer): Cardinal; procedure FreeOverlay(var Buffer: Pointer); implementation uses Windows; // types/defs (mostly Delphi 2/3 stuff) type LONG = Longint; const IMAGE_DOS_SIGNATURE = $5A4D; type TImageDosHeader = packed record e_magic : WORD; e_cblp : WORD; e_cp : WORD; e_crlc : WORD; e_cparhdr : WORD; e_minalloc: WORD; e_maxalloc: WORD; e_ss : WORD; e_sp : WORD; e_csum : WORD; e_ip : WORD; e_cs : WORD; e_lfarlc : WORD; e_ovno : WORD; e_res : array [0..3] of WORD; e_oemid : WORD; e_oeminfo : WORD; e_res2 : array [0..9] of WORD; e_lfanew : LONG; end; TImageFileHeader = packed record Machine : WORD; NumberOfSections : WORD; TimeDateStamp : DWORD; PointerToSymbolTable: DWORD; NumberOfSymbols : DWORD; SizeOfOptionalHeader: WORD; Characteristics : WORD; end; const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16; IMAGE_NT_OPTIONAL_HDR_MAGIC = WORD($010B); type TImageDataDirectory = record VirtualAddress: DWORD; Size : DWORD; end; TImageOptionalHeader = packed record Magic : WORD; MajorLinkerVersion : BYTE; MinorLinkerVersion : BYTE; SizeOfCode : DWORD; SizeOfInitializedData : DWORD; SizeOfUninitializedData : DWORD; AddressOfEntryPoint : DWORD; BaseOfCode : DWORD; BaseOfData : DWORD; ImageBase : DWORD; SectionAlignment : DWORD; FileAlignment : DWORD; MajorOperatingSystemVersion: WORD; MinorOperatingSystemVersion: WORD; MajorImageVersion : WORD; MinorImageVersion : WORD; MajorSubsystemVersion : WORD; MinorSubsystemVersion : WORD; Win32VersionValue : DWORD; SizeOfImage : DWORD; SizeOfHeaders : DWORD; CheckSum : DWORD; Subsystem : WORD; DllCharacteristics : WORD; SizeOfStackReserve : DWORD; SizeOfStackCommit : DWORD; SizeOfHeapReserve : DWORD; SizeOfHeapCommit : DWORD; LoaderFlags : DWORD; NumberOfRvaAndSizes : DWORD; DataDirectory : array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of TImageDataDirectory; end; const IMAGE_NT_SIGNATURE = DWORD($00004550); type TImageNtHeaders = packed record Signature : DWORD; FileHeader : TImageFileHeader; OptionalHeader: TImageOptionalHeader; end; const IMAGE_SIZEOF_SHORT_NAME = 8; type TImageSectionHeader = packed record Name : array [0..IMAGE_SIZEOF_SHORT_NAME - 1] of AnsiChar; Misc : record case Integer of 0: (PhysicalAddress: DWORD); 1: (VirtualSize : DWORD); end; VirtualAddress : DWORD; SizeOfRawData : DWORD; PointerToRawData : DWORD; PointerToRelocations : DWORD; PointerToLinenumbers : DWORD; NumberOfRelocations : WORD; NumberOfLinenumbers : WORD; Characteristics : DWORD; end; // GetOverlay function GetOverlay(var Buffer: Pointer): Cardinal; const INVALID_FILE_SIZE = DWORD(-1); INVALID_SET_FILE_POINTER = DWORD(-1); var FileName: array [0..MAX_PATH] of Char; FileHandle: THandle; FileSizeLo: DWORD; DosHeader: TImageDosHeader; BytesRead: DWORD; NtHeaders: TImageNtHeaders; Offset: DWORD; Section: WORD; SecHeader: TImageSectionHeader; begin Result := 0; Buffer := nil; if GetModuleFileName(HMODULE(nil), FileName, MAX_PATH) <= 0 then Exit; FileHandle := CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, THandle(nil)); if INVALID_HANDLE_VALUE = FileHandle then Exit; try // Get FileSize FileSizeLo := GetFileSize(FileHandle, nil); if INVALID_FILE_SIZE = FileSizeLo then Exit; // Read Headers with DosHeader, NtHeaders, NtHeaders.FileHeader, NtHeaders.OptionalHeader do if not ReadFile(FileHandle, DosHeader, SizeOf(TImageDosHeader), BytesRead, nil) or (BytesRead <> SizeOf(TImageDosHeader)) or (e_magic <> IMAGE_DOS_SIGNATURE) or (e_lfanew < SizeOf(TImageDosHeader)) or (INVALID_SET_FILE_POINTER = SetFilePointer(FileHandle, e_lfanew - SizeOf(TImageDosHeader), nil, FILE_CURRENT)) or not ReadFile(FileHandle, NtHeaders, SizeOf(TImageNtHeaders), BytesRead, nil) or (BytesRead <> SizeOf(TImageNtHeaders)) or (Signature <> IMAGE_NT_SIGNATURE) or (NumberOfSections <= 0) or (SizeOfOptionalHeader < SizeOf(TImageOptionalHeader)) or (INVALID_SET_FILE_POINTER = SetFilePointer(FileHandle, SizeOfOptionalHeader - SizeOf(TImageOptionalHeader), nil, FILE_CURRENT)) then Exit; // Read Sections Offset := 0; for Section := 1 to NtHeaders.FileHeader.NumberOfSections do begin if not ReadFile(FileHandle, SecHeader, SizeOf(TImageSectionHeader), BytesRead, nil) or (BytesRead <> SizeOf(TImageSectionHeader)) then Exit; if Offset < SecHeader.PointerToRawData + SecHeader.SizeOfRawData then Offset := SecHeader.PointerToRawData + SecHeader.SizeOfRawData; end; if Offset <= 0 then Exit; Result := FileSizeLo - Offset; if Result <= 0 then Exit; // Get Overlay Buffer := VirtualAlloc(nil, Result + 1, MEM_COMMIT, PAGE_READWRITE); if not Assigned(Buffer) then begin Result := 0; Exit; end; try if (INVALID_SET_FILE_POINTER = SetFilePointer(FileHandle, Offset, nil, FILE_BEGIN)) or not ReadFile(FileHandle, Buffer^, Result, BytesRead, nil) or (BytesRead <> Result) then begin VirtualFree(Buffer, 0, MEM_RELEASE); Buffer := nil; Result := 0; end else PAnsiChar(Buffer)[Result] := #0; // termiating null for strings except VirtualFree(Buffer, 0, MEM_RELEASE); Buffer := nil; Result := 0; end; finally CloseHandle(FileHandle); end; end; procedure FreeOverlay(var Buffer: Pointer); begin if Assigned(Buffer) then begin VirtualFree(Buffer, 0, MEM_RELEASE); Buffer := nil; end; end; end.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var Size: Cardinal; Buff: Pointer; StrLst: TStringList; Stream: TMemoryStream; begin Size := GetOverlay(Buff); if Assigned(Buff) then try StrLst := TStringList.Create; Stream := TMemoryStream.Create; try Stream.WriteBuffer(Buff^, Size); Stream.Position := 0; StrLst.LoadFromStream(Stream); // TMemIniFile.SetStrings(StrLst); Memo1.Lines.Text := StrLst.Text; finally StrLst.Free; Stream.Free; end; finally FreeOverlay(Buff); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz