2012-11-06 6 views
0

내 응용 프로그램을 고유하게 식별하고 코드 내에서이 값을 얻기 위해 GUID를 사용하려고합니다.DPROJ <ProjectGUID>을 Delphi 코드 내에서 사용하는 방법은 무엇입니까?

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

이 어디 자원으로 예 EXE 파일로 얻을 수 있습니까 : 나는 DPROJ에 이상적 일 것 GUID가 볼? 그렇지 않다면이 GUID 값을 내 exe 파일에 링크하고 코드에서 읽는 가장 깔끔한 방법은 무엇입니까? 위의 GUID는 전용 텍스트 파일에 있으며 내 DprojMaker tool으로 DPROJ에 붙여 넣기 때문에 추천 할만한 것으로 포함시킬 수 있습니다. 감사합니다

답변

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를 코딩 하시겠습니까? 코드 편집기에는 현재 활성 코드 줄에서 새 GUID 문자열을 생성하기위한 키보드 바로 가기 CTRL+SHIFT+G이 있습니다. 이 선언을 필요에 따라 사용할 수있는 상수 변수로 조정할 수 있습니다 (예 :

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

더 나은 방법은 더 이상 액세스 할 수 없으며 컴파일러에서 제거 할 가능성이 적습니다. –