tdxev Posted May 27, 2011 Report Posted May 27, 2011 Încerc sa adaug o icoana la un executabil (cazul de fata este exe consola ).Adaug? resursa dar nu ?tiu unde este problema, am cautat pe google dar nu am g?sit un r?spuns pentru problema asta.Codul de mai jos as vrea sa adauge sau sa modifice icoana unei aplica?ii exe.Nu am nevoie de exemplele de pe msdn ca le-am citit de zece ori./*|| Add icon to executables|*/void addNewIcon(){ std::cout << "Add new icon \n"; HANDLE hFile; DWORD dwFileSize, dwBytesRead; LPBYTE lpBuffer; hFile = CreateFile("c:\\1.ico", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hFile) { dwFileSize = GetFileSize(hFile, NULL); lpBuffer = new BYTE[dwFileSize]; if (ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL) != FALSE) { HANDLE hResource; hResource = BeginUpdateResource("c:\\file.exe", FALSE); if (NULL != hResource) { if (UpdateResource(hResource, RT_ICON, MAKEINTRESOURCE(3), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpBuffer, dwFileSize) != FALSE) { EndUpdateResource(hResource, FALSE); } } } delete [] lpBuffer; CloseHandle(hFile); } return;} Quote
cifratorul Posted May 27, 2011 Report Posted May 27, 2011 ai tinut cont de cache-ul de icoane al windows-ului? google "reset icon cache" poate e de la asta Quote
wildchild Posted May 27, 2011 Report Posted May 27, 2011 uita-te prin codul sursa la "resource hacker".parca era si ceva versiune pentru unix pusa pe source forge, scrisa tot in c++ Quote
tdxev Posted May 27, 2011 Author Report Posted May 27, 2011 am reu?it sa copiez o icoana de la alta aplica?ia la cea care doresc eu folosind exemplu de pe msdn dar tot nu reu?esc sa încarc o icoana (*.ico) pentru un executabil dorit@wildchild o sa caut sa vad dac? o g?sesc@cifratorul din p?cate nu este acolo problema Quote
Nytro Posted May 28, 2011 Report Posted May 28, 2011 Option ExplicitPublic Type ICONDIR idReserved As Integer ' Reserved (must be 0) idType As Integer ' Resource Type (1 for icons) idCount As Integer ' How many images? 'ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)End TypePublic Type ICONDIRENTRY bWidth As Byte ' Width, in pixels, of the image bHeight As Byte ' Height, in pixels, of the image bColorCount As Byte ' Number of colors in image (0 if >=8bpp) bReserved As Byte ' Reserved ( must be 0) wPlanes As Integer ' Color Planes wBitCount As Integer ' Bits per pixel dwBytesInRes As Long ' How many bytes in this resource? dwImageOffset As Long ' Where in the file is this image?End TypePublic Type GRPICONDIR idReserved As Integer ' Reserved (must be 0) idType As Integer ' Resource Type (1 for icons) idCount As Integer ' How many images? 'ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)End TypePublic Type GRPICONDIRENTRY bWidth As Byte ' Width, in pixels, of the image bHeight As Byte ' Height, in pixels, of the image bColorCount As Byte ' Number of colors in image (0 if >=8bpp) bReserved As Byte ' Reserved ( must be 0) wPlanes As Integer ' Color Planes wBitCount As Integer ' Bits per pixel dwBytesInRes As Long ' How many bytes in this resource? dwIconID As Integer ' Where in the file is this image?End TypePublic Type Dat Data() As ByteEnd TypePublic Type Ico IcoDir As ICONDIR Entries() As ICONDIRENTRY IcoData() As DatEnd TypePublic Type IcoExe IcoDir As GRPICONDIR Entries() As GRPICONDIRENTRYEnd TypePrivate Declare Function BeginUpdateResource Lib "kernel32.dll" Alias "BeginUpdateResourceA" (ByVal pFileName As String, ByVal bDeleteExistingResources As Long) As LongPrivate Declare Function UpdateResource Lib "kernel32.dll" Alias "UpdateResourceA" (ByVal hUpdate As Long, ByVal lpType As Long, ByVal lpName As Long, ByVal wLanguage As Long, lpData As Any, ByVal cbData As Long) As LongPrivate Declare Function EndUpdateResource Lib "kernel32.dll" Alias "EndUpdateResourceA" (ByVal hUpdate As Long, ByVal fDiscard As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Const RT_ICON As Long = 3&Private Const DIFFERENCE As Long = 11Private Const RT_GROUP_ICON As Long = (RT_ICON + DIFFERENCE)'// ReplaceIcoInExe "C:\EXEtoReplace.exe", OpenIconFile("C:\NewIcon.ico")Public Function OpenIconFile(FileName As String) As IcoDim t As Ico 'structure temporaireDim X As Long 'compteur'on ouvre le fichierOpen FileName For Binary As #1 'on récup?re l'entete du fichier Get #1, , t.IcoDir 'redimensionne au nombre d'icones ReDim t.Entries(0 To t.IcoDir.idCount - 1) ReDim t.IcoData(0 To t.IcoDir.idCount - 1) 'pour chaque icones For X = 0 To t.IcoDir.idCount - 1 'récup?re l'entete de l'icone Get #1, 6 + 16 * X + 1, t.Entries(X) 'redimensionne ? la taille des données ReDim t.IcoData(X).Data(t.Entries(X).dwBytesInRes - 1) 'récup?re les données Get #1, t.Entries(X).dwImageOffset + 1, t.IcoData(X).Data Next'ferme le fichierClose #1'renvoie les donnéesOpenIconFile = tEnd FunctionPrivate Function MakeIcoExe(IconFile As Ico) As IcoExeDim t As IcoExe 'structure temporaireDim X As Long 'compteur'nombre d'iconest.IcoDir.idCount = IconFile.IcoDir.idCount'type : Icone = 1t.IcoDir.idType = 1'chaque entréeReDim t.Entries(IconFile.IcoDir.idCount - 1)'pour chaque entréeFor X = 0 To t.IcoDir.idCount - 1 'entete d'icones t.Entries(X).bColorCount = IconFile.Entries(X).bColorCount t.Entries(X).bHeight = IconFile.Entries(X).bHeight t.Entries(X).bReserved = IconFile.Entries(X).bReserved t.Entries(X).bWidth = IconFile.Entries(X).bWidth t.Entries(X).dwBytesInRes = IconFile.Entries(X).dwBytesInRes t.Entries(X).dwIconID = X + 1 t.Entries(X).wBitCount = IconFile.Entries(X).wBitCount t.Entries(X).wPlanes = IconFile.Entries(X).wPlanesNext'renvoie la structureMakeIcoExe = tEnd FunctionPublic Function ReplaceIcoInExe(FileName As String, IcoFile As Ico) As BooleanDim hWrite As Long 'handle de modificationDim Exe As IcoExe 'structure de ressource iconeDim ret As Long 'valeur de retourDim X As Long 'compteurDim D() As Byte 'buffer'obtient un handle de modificationhWrite = BeginUpdateResource(FileName, 0)'si échec, on quitteIf hWrite = 0 Then ReplaceIcoInExe = False: Exit Function'sinon, on lit l'iconeExe = MakeIcoExe(IcoFile)'on redimmensionne le bufferReDim D(6 + 14 * Exe.IcoDir.idCount)'on copie les données dans le bufferCopyMemory ByVal VarPtr(D(0)), ByVal VarPtr(Exe.IcoDir), 6'pour chaque iconeFor X = 0 To Exe.IcoDir.idCount - 1 'on copie les données CopyMemory ByVal VarPtr(D(6 + 14 * X)), ByVal VarPtr(Exe.Entries(X).bWidth), 14&Next'on met ? jour la ressource groupe iconeret = UpdateResource(hWrite, RT_GROUP_ICON, 1, 0, ByVal VarPtr(D(0)), UBound(D))'si échec, on quitteIf ret = 0 Then ReplaceIcoInExe = False: EndUpdateResource hWrite, 1: Exit Function'on met ? jour chaque ressource iconeFor X = 0 To Exe.IcoDir.idCount - 1 ret = UpdateResource(hWrite, RT_ICON, Exe.Entries(X).dwIconID, 0, ByVal VarPtr(IcoFile.IcoData(X).Data(0)), Exe.Entries(X).dwBytesInRes)Next'on enregsitre dans le fichier executableret = EndUpdateResource(hWrite, 0)'si échec, on quitteIf ret = 0 Then ReplaceIcoInExe = False: Exit Function'sinon succ?sReplaceIcoInExe = TrueEnd FunctionMaine, daca stau pe acasa, il portez eu in C/C++. Adica azi, ca e aproape 4...Sau asta:Option ExplicitType DIB_HEADER Size As Long Width As Long Height As Long Planes As Integer Bitcount As Integer Reserved As Long ImageSize As LongEnd TypeType ICON_DIR_ENTRY bWidth As Byte bHeight As Byte bColorCount As Byte bReserved As Byte wPlanes As Integer wBitCount As Integer dwBytesInRes As Long dwImageOffset As LongEnd TypeType ICON_DIR Reserved As Integer Type As Integer Count As IntegerEnd TypeType DIB_BITS Bits() As ByteEnd TypePublic Enum Errors FILE_CREATE_FAILED = 1000 FILE_READ_FAILED INVALID_PE_SIGNATURE INVALID_ICO NO_RESOURCE_TREE NO_ICON_BRANCH CANT_HACK_HEADERSEnd EnumPublic Function ReplaceIcons(Source As String, Dest As String, Error As String) As Long Dim IcoDir As ICON_DIR Dim IcoDirEntry As ICON_DIR_ENTRY Dim tBits As DIB_BITS Dim Icons() As IconDescriptor Dim lngRet As Long Dim BytesRead As Long Dim hSource As Long Dim hDest As Long Dim ResTree As Long hSource = CreateFile(Source, ByVal &H80000000, 0, ByVal 0&, 3, 0, ByVal 0) If hSource >= 0 Then If Valid_ICO(hSource) Then SetFilePointer hSource, 0, 0, 0 ReadFile hSource, IcoDir, 6, BytesRead, ByVal 0& ReadFile hSource, IcoDirEntry, 16, BytesRead, ByVal 0& SetFilePointer hSource, IcoDirEntry.dwImageOffset, 0, 0 ReDim tBits.Bits(IcoDirEntry.dwBytesInRes) As Byte ReadFile hSource, tBits.Bits(0), IcoDirEntry.dwBytesInRes, BytesRead, ByVal 0& CloseHandle hSource hDest = CreateFile(Dest, ByVal (&H80000000 Or &H40000000), 0, ByVal 0&, 3, 0, ByVal 0) If hDest >= 0 Then If Valid_PE(hDest) Then ResTree = GetResTreeOffset(hDest) If ResTree > 308 Then ' Sanity check lngRet = GetIconOffsets(hDest, ResTree, Icons) SetFilePointer hDest, Icons(1).Offset, 0, 0 WriteFile hDest, tBits.Bits(0), UBound(tBits.Bits), BytesRead, ByVal 0& If Not HackDirectories(hDest, ResTree, Icons(1).Offset, IcoDirEntry) Then Err.Raise CANT_HACK_HEADERS, App.EXEName, "Unable to modify directories in target executable. File may not contain any icon resources." End If Else Err.Raise NO_RESOURCE_TREE, App.EXEName, Dest & " does not contain a valid resource tree. File may be corrupt." CloseHandle hDest End If Else Err.Raise INVALID_PE_SIGNATURE, App.EXEName, Dest & " is not a valid Win32 executable." CloseHandle hDest End If CloseHandle hDest Else Err.Raise FILE_CREATE_FAILED, App.EXEName, "Failed to open " & Dest & ". Make sure file is not in use by another program." End If Else Err.Raise INVALID_ICO, App.EXEName, Source & " is not a valid icon resource file." CloseHandle hSource End If Else Err.Raise FILE_CREATE_FAILED, App.EXEName, "Failed to open " & Source & ". Make sure file is not in use by another program." End If ReplaceIcons = 0 Exit FunctionErrHandler: ReplaceIcons = Err.Number Error = Err.DescriptionEnd FunctionPublic Function Valid_ICO(hFile As Long) As Boolean Dim tDir As ICON_DIR Dim BytesRead As Long If (hFile > 0) Then ReadFile hFile, tDir, Len(tDir), BytesRead, ByVal 0& If (tDir.Reserved = 0) And (tDir.Type = 1) And (tDir.Count > 0) Then Valid_ICO = True Else Valid_ICO = False End If Else Valid_ICO = False End IfEnd FunctionAm niste probleme stupide, pe o structura din C. "Imi sare" peste un cam din structura, ca si cum nu ar fi. Sa vad daca reusesc sa scap de problema. Quote
Nytro Posted May 28, 2011 Report Posted May 28, 2011 Nu stiu de ce nu merge. De fapt schimba iconita, dar STRICA executabilul. Poate te ajuta cu ceva:/* Nume: Icon Changer portat din Visual Basic 6 Autor: Gheorghe Vasile Status: Functionare partiala*/#include <stdio.h>#include <stdlib.h>#include <windows.h>typedef struct ICONDIR{ short idReserved; short idType; short idCount;} ICONDIR;typedef struct ICONDIRENTRY{ unsigned char bWidth; unsigned char bHeight; unsigned char bColorCount; unsigned char bReserved; short wPlanes; short wBitCount; int dwBytesInRes; int dwImageOffset;} ICONDIRENTRY;typedef struct GRPICONDIR{ short idReserved; short idType; short idCount;} GRPICONDIR;typedef struct GRPICONDIRENTRY{ unsigned char bWidth; unsigned char bHeight; unsigned char bColorCount; unsigned char bReserved; short wPlanes; short wBitCount; long dwBytesInRes; long dwIconID;} GRPICONDIRENTRY;typedef struct Dat{ unsigned char *Data;} Dat;typedef struct Ico{ ICONDIR IcoDir; ICONDIRENTRY *Entries; Dat *IcoData;} Ico;typedef struct IcoExe{ GRPICONDIR IcoDir; GRPICONDIRENTRY *Entries;} IcoExe;Ico OpenIconFile(const char *Filename){ Ico t; FILE *fisier; int i; fisier = fopen(Filename, "rb"); fread(&t.IcoDir, sizeof(ICONDIR), 1, fisier); t.Entries = (ICONDIRENTRY *)malloc(sizeof(ICONDIRENTRY) * t.IcoDir.idCount); t.IcoData = (Dat *)malloc(sizeof(Dat) * t.IcoDir.idCount); for(i = 0; i <= t.IcoDir.idCount - 1; i++) { fseek(fisier, 6 + (16 * i), SEEK_SET); fread(&t.Entries[i], sizeof(ICONDIRENTRY), 1, fisier); t.IcoData[i].Data = (unsigned char *)malloc(t.Entries[i].dwBytesInRes); fseek(fisier, t.Entries[i].dwImageOffset, SEEK_SET); t.IcoData[i].Data = (unsigned char *)malloc(t.Entries[i].dwBytesInRes); fread(t.IcoData[i].Data, t.Entries[i].dwBytesInRes, 1, fisier); } fclose(fisier); return t;}IcoExe MakeIcoExe(Ico IconFile){ IcoExe t; long i; t.IcoDir.idCount = IconFile.IcoDir.idCount; t.IcoDir.idType = 1; t.IcoDir.idReserved = 0; t.Entries = (GRPICONDIRENTRY *)malloc(sizeof(GRPICONDIRENTRY) * t.IcoDir.idCount); for(i = 0; i <= t.IcoDir.idCount - 1; i++) { t.Entries[i].bColorCount = IconFile.Entries[i].bColorCount; t.Entries[i].bHeight = IconFile.Entries[i].bHeight; t.Entries[i].bReserved = IconFile.Entries[i].bReserved; t.Entries[i].bWidth = IconFile.Entries[i].bWidth; t.Entries[i].dwBytesInRes = IconFile.Entries[i].dwBytesInRes; t.Entries[i].dwIconID = i + 1; t.Entries[i].wBitCount = IconFile.Entries[i].wBitCount; t.Entries[i].wPlanes = IconFile.Entries[i].wPlanes; } return t;}int ReplaceIcoInExe(const char *FileName, Ico IcoFile){ int ret, i, aux; HANDLE hWrite; IcoExe Exe; unsigned char *D; hWrite = BeginUpdateResource(FileName, 0); Exe = MakeIcoExe(IcoFile); aux = 6 + 14 * Exe.IcoDir.idCount; D = (unsigned char *)malloc(aux); CopyMemory(D, &Exe.IcoDir, 6); for(i = 0; i <= Exe.IcoDir.idCount - 1; i++) { CopyMemory(&D[6 + 14 * i], &Exe.Entries[i], 14); } ret = UpdateResource(hWrite, RT_GROUP_ICON, MAKEINTRESOURCE(1), 0, D, aux); if(ret == 0) { EndUpdateResource(hWrite, 1); return 0; } for(i = 0; i <= Exe.IcoDir.idCount - 1; i++) { ret = UpdateResource(hWrite, RT_ICON, MAKEINTRESOURCE(Exe.Entries[i].dwIconID), 0, IcoFile.IcoData[i].Data, Exe.Entries[i].dwBytesInRes); } ret = EndUpdateResource(hWrite, 0); if(ret == 0) return 0; else return 1;}int main(){ printf("Rezultat: %d\n\n", ReplaceIcoInExe("F:\\x.exe", OpenIconFile("F:\\g.ico"))); return 0;} 1 Quote
tdxev Posted May 28, 2011 Author Report Posted May 28, 2011 merci Nytro! o sa încerc sa vad dac? reu?esc..Later:- am f?cut proba pe aplica?ii ?i într-adev?r pe unele le strica, - am testat pe acelea?i aplica?ii ?i cu XN Resource Editor ?i nici el nu se descurca mai bine (?i el stric? aplica?iile, în majoritatea cazurilor acestea fiind installer-e)- partea buna este ca pentru aplica?ia(consola) pentru care aveam nevoie merge perfect Quote
Nytro Posted May 28, 2011 Report Posted May 28, 2011 Cu placere.Cred ca buba e la "ReplaceIcoInExe". Am verificat valorile datelor din celelalte functii si nu am gasit probleme. Codul original in VB6 foloseste dimensiuni fixe pentru structuri ca 6, 16... Si:aux = 6 + 14 * Exe.IcoDir.idCount;Cred ca e de fapt: aux = 6 + 16 * Exe.IcoDir.idCount;Deoarece acea structura cred ca e de sizeof() == 16.Problema e probabil sa fie la ret = UpdateResource(hWrite, RT_GROUP_ICON, MAKEINTRESOURCE(1), 0, D, aux);sau la celalalt apel al acestei functii. Am avut probleme, in VB6 erau declarate cu parametrii de tip Long 2 dintre parametrii, si sunt de fapt LPTCSTR. Ma mai uit peste el, poate gasesc problema... Ciudat e ca imi facea executabilul mult mai mic. Quote