2012-11-06 15 views
0

我想用一个GUID来唯一标识我的应用程序,并在此值从代码中获得。我看到有一个GUID,这将是理想的DPROJ:如何使用DPROJ <ProjectGUID> Delphi代码内?

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
     <ProjectGuid>{D4DB842C-FB4C-481B-8952-77DA04E37102}</ProjectGuid> 

这是否进入exe文件的任何地方,例如作为一种资源?如果没有,将这个GUID值链接到我的exe文件并在代码中读取它的最新方法是什么?上述GUID驻留在一个专用的文本文件,并粘贴到DPROJ我DprojMaker tool,这样我就可以在任何你可能会建议包括它。 谢谢

回答

3

AFAIK <ProjectGUID>没有嵌入到EXE文件中,但是你可以创建一个应用程序来读取项目GUID并作为资源插入到你的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. 
从您的应用程序

现在,你可以使用后生成的事件来呼吁这样

"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. 
+0

完美答案。谢谢 –

+0

预构建事件不会更容易吗? –

2

为什么不硬在自己的代码中编写自己的GUID?代码编辑器有一个CTRL+SHIFT+G键盘快捷键,用于在当前活动代码行生成新的GUID字符串。您可以将该声明调整为一个常量,以便您的代码根据需要使用,例如:

const 
    MyGuid: TGUID = '{04573E0E-DE08-4796-A5BB-E5F1F17D51F7}'; 
+0

更好的是,使它成为一个资源字符串,它将更容易访问,并且不太可能被编译器消除。 –