Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Переименовать производителя проги


Автор: Delphist 22.10.2004, 17:26
Как средствами Delphi7 переименовать имя производителя, название проги (они вшиваются в PE файл при его создании), вообщем все то что отображается при свойствах файла.

Автор: Pakshin A. S. 22.10.2004, 17:29
Ручками найти в фале еначальный быйт записи информациии (похоже он гже-то в конце, можно через Far почитать); записать туда новую информацию; переделать длину файла (как это делают вирусы)... :( :)

Автор: p0s0l 22.10.2004, 17:34
Зачем же так ?
Project -> Options -> Version Info
ставим галочку, и заполняем инфу...

Автор: Pakshin A. S. 22.10.2004, 19:21
По всей видимости, человеку нужно переименовать это в чужой программе... :(

Автор: Alex 22.10.2004, 21:10
если в чужой то это не есть хорошо, ну если очень хочется, то эта информация хранится в ресурсах.

Автор: p0s0l 22.10.2004, 21:57
Цитата
По всей видимости, человеку нужно переименовать это в чужой программе...
Мдя ?... Ну ладно, будет тогда так:
Код
var ResName : PChar; // эта переменная нужна!

procedure ChangeCompany (FileName : string; NewCompany : string);
const CompanyName = 'CompanyName';
var
 hUpdate : THandle;
 hExe : HMODULE;
 Data : WideString;
 ResInfo : HRSRC;
 ResData : HGLOBAL;
 Adr : Pointer;
 Size : DWORD;
 i0, i, l : integer;

 function EnumFunc (hMod : HMODULE; lpszType : LPCTSTR; lpszName : LPTSTR; lParam : integer) : BOOL; stdcall;
 begin
   ResName := lpszName;
   Result := False;
 end;

begin
 hExe := LoadLibrary (PChar(FileName));
 if hExe = 0 then Exit;
 ResName := nil;
 EnumResourceNames (hExe, RT_VERSION, @EnumFunc, 0);
 ResInfo := FindResource (hExe, ResName, RT_VERSION);
 if ResInfo = 0 then Exit;
 ResData := LoadResource (hExe, ResInfo);
 Adr := LockResource (ResData);
 Size := SizeofResource (hExe, ResInfo);
 SetLength(Data, Size div 2);
 CopyMemory (@Data[1], Adr, Size);
 FreeResource (ResData);
 FreeLibrary (hExe);

 i0 := Pos(CompanyName, Data);
 i := i0 + Length(CompanyName);
 while Data[i] = #0 do Inc(i);
 l := 0;
 while Data[i+l] <> #0 do Inc(l);
 while Data[i+l] = #0 do Inc(l);
 Delete (Data, i, l);

 NewCompany := NewCompany + #0;
 Data[i0-2] := WideChar(Length(NewCompany));
 while (Length(NewCompany) mod 2) <> 0 do NewCompany := NewCompany + #0;
 Insert (NewCompany, Data, i);
 Data[i0-3] := WideChar( Word(Data[i0-3]) + (Length(NewCompany) - l)*2 );

 i0 := Pos('StringFileInfo', Data);
 Data[i0-3] := WideChar( Word(Data[i0-3]) + (Length(NewCompany) - l)*2 );

 Size := Length(Data)*2;
 Data[1] := WideChar(Size);
 
 hUpdate := BeginUpdateResource (PChar(FileName), False);
 UpdateResource (hUpdate, RT_VERSION, ResName, 1049, @Data[1], Size);
 EndUpdateResource (hUpdate, False);
end;


Пример вызова:
Код
procedure TForm1.Button1Click(Sender: TObject);
begin
 ChangeCompany ('c:\project1.exe', 'Posol');
end;


Автор: Alex 23.10.2004, 09:41
p0s0l по сути, ты конечно дал правильный пример, но во первых он будет работать только в NT системах т.к. функции *UpdateResource присутствуют только в NT, а во вторых ты в UpdateResource жестко задал язык ресурса 1049 (Русский) сам понимаешь, что это не хорошо.

Автор: p0s0l 23.10.2004, 10:31
Цитата
1049 (Русский)
Спасибо, что сказал. Я для теста сделал без определения языка, и так потом и забыл сделать определение языка...
Щас подправлю...


Автор: p0s0l 23.10.2004, 11:31
Код
var ResName : PChar; // эта переменная нужна!

procedure ChangeCompany (FileName : string; NewCompany : string);
const
 StringFileInfo = 'StringFileInfo';
 CompanyName = 'CompanyName';
 
var
 hUpdate : THandle;
 hExe : HMODULE;
 Data : WideString;
 ResInfo : HRSRC;
 ResData : HGLOBAL;
 Adr : Pointer;
 Size : DWORD;
 i0, i00, i, l, delta : integer;
 NewCompanyZ : string;
 LangID : word;

 function EnumFunc (hMod : HMODULE; lpszType : LPCTSTR; lpszName : LPTSTR; lParam : integer) : BOOL; stdcall;
 begin
   ResName := lpszName;
   Result := False;
 end;

begin
 hExe := LoadLibrary (PChar(FileName));
 if hExe = 0 then Exit;
 ResName := nil;
 EnumResourceNames (hExe, RT_VERSION, @EnumFunc, 0);
 ResInfo := FindResource (hExe, ResName, RT_VERSION);
 if ResInfo = 0 then Exit;
 ResData := LoadResource (hExe, ResInfo);
 Adr := LockResource (ResData);
 Size := SizeofResource (hExe, ResInfo);
 SetLength(Data, Size div 2);
 CopyMemory (@Data[1], Adr, Size);
 FreeResource (ResData);
 FreeLibrary (hExe);

 NewCompanyZ := NewCompany + #0;
 while (Length(NewCompanyZ) mod 2) <> 0 do NewCompanyZ := NewCompanyZ + #0;

 i00 := Pos(StringFileInfo, Data);
 if i00 = 0 then Exit;

 i0 := PosEx(CompanyName, Data, i00);
 if i0 = 0 then Exit;

 i := i0 + Length(CompanyName);
 while Data[i] = #0 do Inc(i);
 l := 0;
 while Data[i+l] <> #0 do Inc(l);
 while Data[i+l] = #0 do Inc(l);
 Delete (Data, i, l);
 Insert (NewCompanyZ, Data, i);

 delta := (Length(NewCompanyZ) - l);
 Data[i0-3] := WideChar( Word(Data[i0-3]) + delta*2 ); // размер CompanyName
 Data[i0-2] := WideChar(Length(NewCompany)+1); // длина нового производителя
 Data[i00-3] := WideChar( Word(Data[i00-3]) + delta*2 ); // размер StringFileInfo
 i := i00+Length(StringFileInfo)+1;
 Data[i] := WideChar( Word(Data[i]) + delta*2 ); // размер языковой инфы
 Size := Length(Data)*2;
 Data[1] := WideChar(Size);

 Inc(i, 3);
 LangId := StrToInt('$' + Copy(Data, i, 4));

 hUpdate := BeginUpdateResource (PChar(FileName), False);
 UpdateResource (hUpdate, RT_VERSION, ResName, LangId, @Data[1], Size);
 EndUpdateResource (hUpdate, False);
end;
По смыслу надо предусмотреть возможность наличия инфы о версии в нескольких языках, но это удовольствие я оставлю для автора темы :), т.к. для испытания этого у себя я таких многоязыковых файлов не нашёл...

Автор: Alex 23.10.2004, 22:18
А я бы сделал так:
Код
uses
 acWorkRes;
...

threadvar
 ResName : PChar; // эта переменная нужна!

procedure ChangeCompany (FileName : string; NewCompany : string);
const
 StringFileInfo = 'StringFileInfo';
 CompanyName = 'CompanyName';

var
 hUpdate : THandle;
 hExe : HMODULE;
 Data : WideString;
 ResInfo : HRSRC;
 ResData : HGLOBAL;
 Adr : Pointer;
 Size : DWORD;
 i0, i00, i, l, delta : integer;
 NewCompanyZ : string;

 function EnumFunc (hMod : HMODULE; lpszType : LPCTSTR; lpszName : LPTSTR; lParam : integer) : BOOL; stdcall;
 begin
  ResName := lpszName;
  Result := False;
 end;

begin
 hExe := LoadLibrary (PChar(FileName));
 if hExe = 0 then Exit;
 ResName := nil;
 EnumResourceNames (hExe, RT_VERSION, @EnumFunc, 0);

 ResInfo := FindResource (hExe, ResName, RT_VERSION);
 if ResInfo = 0 then Exit;
 ResData := LoadResource (hExe, ResInfo);
 Adr := LockResource (ResData);
 Size := SizeofResource (hExe, ResInfo);
 SetLength(Data, Size div 2);
 CopyMemory (@Data[1], Adr, Size);
 FreeResource (ResData);
 FreeLibrary (hExe);

 NewCompanyZ := NewCompany + #0;
 while (Length(NewCompanyZ) mod 2) <> 0 do NewCompanyZ := NewCompanyZ + #0;

 i00 := Pos(StringFileInfo, Data);
 if i00 = 0 then Exit;

 i0 := PosEx(CompanyName, Data, i00);
 if i0 = 0 then Exit;

 i := i0 + Length(CompanyName);
 while Data[i] = #0 do Inc(i);
 l := 0;
 while Data[i+l] <> #0 do Inc(l);
 while Data[i+l] = #0 do Inc(l);
 Delete (Data, i, l);
 Insert (NewCompanyZ, Data, i);

 delta := (Length(NewCompanyZ) - l);
 Data[i0-3] := WideChar( Word(Data[i0-3]) + delta*2 ); // размер CompanyName
 Data[i0-2] := WideChar(Length(NewCompany)+1); // длина нового производителя
 Data[i00-3] := WideChar( Word(Data[i00-3]) + delta*2 ); // размер StringFileInfo

 Size := Length(Data)*2;
 Data[1] := WideChar(Size);

 hUpdate := BeginUpdateResourceW(StringToPWide(FileName), False);
 notLang:= True;
 try
   UpdateResourceW(hUpdate, PWideChar(RT_VERSION), PWideChar(ResName), 0, @Data[1], Size);
 finally
   notLang:= False;
 end;
 EndUpdateResourceW(hUpdate, False);
end;

Добавлено @ 22:21
Скачать и прочитать о модуле acWorkRes можно здесь http://forum.vingrad.ru/index.php?showtopic=21183

Автор: p0s0l 24.10.2004, 04:07
Alex, а без дополнительных библиотек слабо ? :p
Только в чём заключается отличие ? Я мотал туда-сюда, вроде есть отличия, но не значительные... Единственное, что настораживает - это таинственная переменная notLang - зачем она введена ? И переход на Unicode-функции BeginUpdate, Update, EndUpdate... В чём преимущество этого перехода ? Имена ресурсов в файле все равно не уникодовые... А инфа о версии всё равно в любом случае уникодовая, даже если пользоваться анси-функциями (как в моём случае: Data ведь WideString, а не AnsiString)...
Если ради имени файла, то тогда LoadLibrary тоже надо Wideом сделать...
Объясни, плиз... (мне просто интересно, скорее всего я что-то упустил и не знаю того, чего знаешь ты...)
Хотя может это сон на меня наваливается, и я уже ничего не понимаю... :)

Автор: Alex 24.10.2004, 10:30
Цитата(p0s0l @ 24.10.2004, 05:07)
Alex, а без дополнительных библиотек слабо ? 
Только в чём заключается отличие ? Я мотал туда-сюда, вроде есть отличия, но не значительные... Единственное, что настораживает - это таинственная переменная notLang - зачем она введена ? И переход на Unicode-функции BeginUpdate, Update, EndUpdate... В чём преимущество этого перехода ? Имена ресурсов в файле все равно не уникодовые... А инфа о версии всё равно в любом случае уникодовая, даже если пользоваться анси-функциями (как в моём случае: Data ведь WideString, а не AnsiString)...
Если ради имени файла, то тогда LoadLibrary тоже надо Wideом сделать...
Объясни, плиз... (мне просто интересно, скорее всего я что-то упустил и не знаю того, чего знаешь ты...)
Хотя может это сон на меня наваливается, и я уже ничего не понимаю... 

Ну вот приехали, здрасте, а кто целый раздел “арсенал форума” создавал под модуль acWorkRes. :( В модуле реализованы СВОИ функции *UpdateResource сделано это было для того чтобы можно было использовать эти функции не только в NT, но и в 9х системах. Плюс в этих функциях нет ошибок, которые присутствуют в стандартных функциях при работе с иконками, в модуле присутствуют несколько функций для упрощенной работы с картинками иконками и файлами, которые хранятся в ресурсах. И т.к. в большинстве случаев язык ресурса нам не важен, то при установке переменной notLang в истину модуль перестает обращать внимание на язык ресурса при работе с ним. Так что выбирать, конечно, программисту пользоваться моим модулем или нет, но я лично пишу программы, которые должны запускаться под виндами от 95 до 2003 и мне этот модуль был необходим как воздух.

Автор: p0s0l 24.10.2004, 12:19
Вот и разгадка :)
Ты обозвал свои функции в модуле также, как и в WinAPI, я даже и не подумал, что это твои функции...
Ну тогда всё встаёт на свои места... :)

Автор: Delphist 26.10.2004, 11:23
Цитата(Alex @ 23.10.2004, 22:18)
А я бы сделал так:
Код
uses
 acWorkRes;
...

threadvar
 ResName : PChar; // эта переменная нужна!

procedure ChangeCompany (FileName : string; NewCompany : string);
const
 StringFileInfo = 'StringFileInfo';
 CompanyName = 'CompanyName';

var
 hUpdate : THandle;
 hExe : HMODULE;
 Data : WideString;
 ResInfo : HRSRC;
 ResData : HGLOBAL;
 Adr : Pointer;
 Size : DWORD;
 i0, i00, i, l, delta : integer;
 NewCompanyZ : string;

 function EnumFunc (hMod : HMODULE; lpszType : LPCTSTR; lpszName : LPTSTR; lParam : integer) : BOOL; stdcall;
 begin
  ResName := lpszName;
  Result := False;
 end;

begin
 hExe := LoadLibrary (PChar(FileName));
 if hExe = 0 then Exit;
 ResName := nil;
 EnumResourceNames (hExe, RT_VERSION, @EnumFunc, 0);

 ResInfo := FindResource (hExe, ResName, RT_VERSION);
 if ResInfo = 0 then Exit;
 ResData := LoadResource (hExe, ResInfo);
 Adr := LockResource (ResData);
 Size := SizeofResource (hExe, ResInfo);
 SetLength(Data, Size div 2);
 CopyMemory (@Data[1], Adr, Size);
 FreeResource (ResData);
 FreeLibrary (hExe);

 NewCompanyZ := NewCompany + #0;
 while (Length(NewCompanyZ) mod 2) <> 0 do NewCompanyZ := NewCompanyZ + #0;

 i00 := Pos(StringFileInfo, Data);
 if i00 = 0 then Exit;

 i0 := PosEx(CompanyName, Data, i00);
 if i0 = 0 then Exit;

 i := i0 + Length(CompanyName);
 while Data[i] = #0 do Inc(i);
 l := 0;
 while Data[i+l] <> #0 do Inc(l);
 while Data[i+l] = #0 do Inc(l);
 Delete (Data, i, l);
 Insert (NewCompanyZ, Data, i);

 delta := (Length(NewCompanyZ) - l);
 Data[i0-3] := WideChar( Word(Data[i0-3]) + delta*2 ); // размер CompanyName
 Data[i0-2] := WideChar(Length(NewCompany)+1); // длина нового производителя
 Data[i00-3] := WideChar( Word(Data[i00-3]) + delta*2 ); // размер StringFileInfo

 Size := Length(Data)*2;
 Data[1] := WideChar(Size);

 hUpdate := BeginUpdateResourceW(StringToPWide(FileName), False);
 notLang:= True;
 try
   UpdateResourceW(hUpdate, PWideChar(RT_VERSION), PWideChar(ResName), 0, @Data[1], Size);
 finally
   notLang:= False;
 end;
 EndUpdateResourceW(hUpdate, False);
end;

Добавлено @ 22:21
Скачать и прочитать о модуле acWorkRes можно здесь http://forum.vingrad.ru/index.php?showtopic=21183

Вместо того, чтобы переименовать производителя, твой код удаляет всю инфу о версии файла.
Я попробовал код p0s0l'a тоже самое!!!

Автор: p0s0l 26.10.2004, 11:44
Delphist, выложи или пришли на мыло тот файл, у которого портится инфа о версии...
Потому как у меня всё нормально переименовывется - пробовал файлах на 10...
PS: ты который мой вариант пробовал - первый или второй ? Надо второй...

Автор: Delphist 26.10.2004, 12:01
Цитата(p0s0l @ 26.10.2004, 11:44)
Delphist, выложи или пришли на мыло тот файл, у которого портится инфа о версии...
Потому как у меня всё нормально переименовывется - пробовал файлах на 10...
PS: ты который мой вариант пробовал - первый или второй ? Надо второй...

Пробовал и превый и второй вариант.

Автор: p0s0l 26.10.2004, 12:19
Delphist, пришли этот файл....

Автор: Alex 26.10.2004, 16:58
Delphist И мне пришли

Автор: Akella 25.12.2004, 11:01
Delphist И мне пришли smile

Автор: Guest 16.2.2005, 08:21
Господа! Это мы поменяли только имя компании-производителя. А как быть со всем остальным? Вызывать ChangeCompany для каждого параметра с изменёнными StringFileInfo и CompanyName?
И ещё - что это за функция PosEx()? У меня выдаем, что такой не знает. Какой модуль подключить?

Автор: Vit 16.2.2005, 16:51
Цитата(Guest @ 15.2.2005, 23:21)
И ещё - что это за функция PosEx()



Стандартная в Дельфи, может у вас старая версия Дельфи

Автор: Alex 17.2.2005, 09:01
Цитата(Guest @ 16.2.2005, 08:21)
Господа! Это мы поменяли только имя компании-производителя. А как быть со всем остальным? Вызывать ChangeCompany для каждого параметра с изменёнными StringFileInfo и CompanyName?

Если не переписывать полностью функцию то да.

Автор: madbrain 26.10.2009, 11:00
Таже проблема. Правда я на VB6 пробывал решить.
Файлы прикрепил, до и после.


Код

Private Declare Function BeginUpdateResource Lib "kernel32.dll" Alias "BeginUpdateResourceA" (ByVal pFileName As String, ByVal bDeleteExistingResources As Long) As Long
Private Declare Function UpdateResource Lib "kernel32.dll" Alias "UpdateResourceA" (ByVal hUpdate As Long, ByVal lpType As Long, ByVal lpName As Long, ByVal wLanguage As Long, ByRef lpData As Any, ByVal cbData As Long) As Long
Private Declare Function EndUpdateResource Lib "kernel32.dll" Alias "EndUpdateResourceA" (ByVal hUpdate As Long, ByVal fDiscard As Long) As Long
Private Declare Function GetFileVersionInfoSize Lib "Version.dll" Alias "GetFileVersionInfoSizeA" (ByVal sFile As String, lpLen As Long) As Long
Private Declare Function GetFileVersionInfo Lib "Version.dll" Alias "GetFileVersionInfoA" (ByVal lptstrFilename As String, ByVal dwhandle As Long, ByVal dwlen As Long, lpData As Any) As Long

Private Const RT_VERSION As Long = 16

Private Sub UPDRES(FName As String)
lVerSize = GetFileVersionInfoSize(FName, lTemp)
ReDim IPData(lVerSize)
Ret = GetFileVersionInfo(FName, 0, lVerSize, IPData(0))

Hndl = BeginUpdateResource(FName, False)
Ret = UpdateResource(Hndl, RT_VERSION, 1, 1033, VarPtr(IPData(0)), UBound(IPData)) 
EndUpdateResource Hndl, False
End Sub

Как видите, ничего не меняю, просто считываю, и записываю инфу обратно. Несмотря на это, ничего не получается. Может подскажете где ошибка?
Чуствую что прийдётся отказатся от UpdateResource, и писать всё ручками.

Автор: madbrain 26.10.2009, 11:17
http://support.microsoft.com/kb/833659

У меня WinXP SP3


Цитата("kernel32.dll")

Version language : Русский
      CompanyName    : Корпорация Майкрософт
      FileDescription    : Библиотека клиента Windows NT BASE API
      FileVersion    : 5.1.2600.5512 (xpsp.080413-2111)
      InternalName    : kernel32
      LegalCopyright    : © Корпорация Майкрософт. Все права защищены.
      OriginalFilename    : kernel32
      ProductName    : Операционная система Microsoft® Windows®
      ProductVersion    : 5.1.2600.5512

Creation Date    : 16/04/2008  04:00:00 
Last Modif. Date    : 16/04/2008  04:00:00 
Last Access Date    : 01/01/2002  00:00:00 
FileSize    : 995840 bytes ( 972.500 KB,  0.950 MB ) 
FileVersionInfoSize    : 1876 bytes  
File type    : Dynamic Link Library (0x2) 
Target OS    : Win32 API (Windows NT) (0x40004) 
File/Product version    : 5.1.2600.5512 / 5.1.2600.5512
Language  : Русский (0x419) 
Character Set    : 1200 (ANSI - Unicode (BMP of ISO 10646)) (0x4B0) 


Автор: Акакий 4.3.2010, 14:28
Так и не решен вопрос, почему вместо изменения CompanyName вся инфа RT_VERSION просто удаляется? Пробовал примеры p0s0l'a и Alex'a - на любых ехе-шниках просто удаляется RT_VERSION и все. Ось WinXP SP2.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)