Как использовать DPROJ <ProjectGUID> в коде Delphi?
Я хочу использовать GUID, чтобы однозначно идентифицировать мое приложение и получить это значение из кода. Я вижу, что в DPROJ есть идеальный GUID:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{D4DB842C-FB4C-481B-8952-77DA04E37102}</ProjectGuid>
Это попадает в exe где-нибудь, например, как ресурс? Если нет, то как лучше всего связать это значение GUID с моим exe-файлом и прочитать его в коде. Указанный выше GUID находится в специальном текстовом файле и вставляется в DPROJ с помощью моего инструмента DprojMaker, поэтому я могу ВКЛЮЧИТЬ его во все, что вы могли бы предложить. Спасибо
2 ответа
AFAIK <ProjectGUID>
не встроен в файл Exe, но вы можете создать приложение для чтения руководства проекта и вставки в качестве ресурса в ваш exe.
Проверьте этот пример приложения, которое читает файл, создает / обновляет ресурс в exe.
program UpdateResEXE;
{$APPTYPE CONSOLE}
uses
Classes,
Windows,
SysUtils;
//you can improve this method to read the ProjectGUID value directly from the dproj file using XML.
procedure UpdateExeResource(Const Source, ResourceName, ExeFile:string);
var
LStream : TFileStream;
hUpdate : THANDLE;
lpData : Pointer;
cbData : DWORD;
begin
LStream := TFileStream.Create(Source,fmOpenRead or fmShareDenyNone);
try
LStream.Seek(0, soFromBeginning);
cbData:=LStream.Size;
if cbData>0 then
begin
GetMem(lpData,cbData);
try
LStream.Read(lpData^, cbData);
hUpdate:= BeginUpdateResource(PChar(ExeFile), False);
if hUpdate <> 0 then
if UpdateResource(hUpdate, RT_RCDATA, PChar(ResourceName),0,lpData,cbData) then
begin
if not EndUpdateResource(hUpdate,FALSE) then RaiseLastOSError
end
else
RaiseLastOSError
else
RaiseLastOSError;
finally
FreeMem(lpData);
end;
end;
finally
LStream.Free;
end;
end;
begin
try
if ParamCount<>3 then
begin
Writeln('Wrong parameters number');
Halt(1);
end;
Writeln(Format('Adding/Updating resource %s in %s',[ParamStr(2), ParamStr(3)]));
UpdateExeResource( ParamStr(1), ParamStr(2), ParamStr(3));
Writeln('Done');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Теперь из вашего приложения вы можете использовать события Post build для вызова этого приложения таким образом
"C:\The path where is the tool goes here\UpdateResEXE.exe" "C:\The path of the file which contains the ProjectGUID goes here\Foo.txt" Project_GUID "$(OUTPUTPATH)"
И использовать так:
{$APPTYPE CONSOLE}
uses
Windows,
Classes,
System.SysUtils;
function GetProjectGUID : string;
var
RS: TResourceStream;
SS: TStringStream;
begin
RS := TResourceStream.Create(HInstance, 'Project_GUID', RT_RCDATA);
try
SS:=TStringStream.Create;
try
SS.CopyFrom(RS, RS.Size);
Result:= SS.DataString;
finally
SS.Free;
end;
finally
RS.Free;
end;
end;
begin
try
Writeln(Format('Project GUID %s',[GetProjectGUID]));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.
Почему бы просто не кодировать свой собственный GUID внутри самого кода? Редактор кода имеет CTRL+SHIFT+G
сочетание клавиш для генерации новой строки GUID в текущей активной строке кода. Вы можете настроить это объявление в константную переменную, чтобы ваш код мог использовать ее по мере необходимости, например:
const
MyGuid: TGUID = '{04573E0E-DE08-4796-A5BB-E5F1F17D51F7}';