mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-10 21:02:38 +02:00
186 lines
6.4 KiB
ObjectPascal
186 lines
6.4 KiB
ObjectPascal
{
|
|
/***************************************************************************
|
|
w32manifest.pas - Lazarus IDE unit
|
|
---------------------------------------
|
|
TProjectXPManifest is responsible for the inclusion of the
|
|
manifest in windows executables.
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
* *
|
|
***************************************************************************
|
|
}
|
|
unit W32Manifest;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Process, LCLProc, Controls, Forms,
|
|
CodeToolManager, CodeCache, CodeAtom, LazConf, SourceChanger, LResources;
|
|
|
|
type
|
|
{ TProjectXPManifest }
|
|
|
|
TProjectXPManifest = class(TObject)
|
|
private
|
|
FMessages: TStrings;
|
|
FUseManifest: boolean;
|
|
resFilename: string;
|
|
procedure SetUseManifest(const AValue: boolean);
|
|
procedure SetFileNames(const MainFilename: string);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
|
|
function CompileRCFile(const MainFilename, TargetOS: string): TModalResult;
|
|
function CreateManifest: Boolean;
|
|
function UpdateMainSourceFile(const AFilename: string): TModalResult;
|
|
|
|
property Messages: TStrings read FMessages;
|
|
property UseManifest: boolean read FUseManifest write SetUseManifest;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{-----------------------------------------------------------------------------
|
|
TProjectXPManifest CompileRCFile
|
|
-----------------------------------------------------------------------------}
|
|
function TProjectXPManifest.CompileRCFile(const MainFilename, TargetOS: string): TModalResult;
|
|
begin
|
|
// in future we will compile manifest from rc, but now we just add our template
|
|
|
|
Result := mrOk;
|
|
SetFileNames(MainFilename);
|
|
if (TargetOS = 'win32') and UseManifest then
|
|
begin
|
|
if not CreateManifest then
|
|
Result := mrCancel;
|
|
end;
|
|
end;
|
|
|
|
function TProjectXPManifest.CreateManifest: Boolean;
|
|
var
|
|
Res: TLResource;
|
|
Stream: TStream;
|
|
begin
|
|
// here will be better to compile res from rc, but we will only extract
|
|
// precompiled res from lazarus resource due to error in windres.
|
|
|
|
// Error description:
|
|
// if we compile manifest by windres then we will not link our project if we
|
|
// have other res files before manifest (I tested with version info resource)
|
|
// But if we compile that manifest.rc with other resource compiler then we have
|
|
// not such errors. So at this moment we decided to extract precompiled res insted
|
|
// of have problems with rc compilation and further linking
|
|
|
|
Result := False;
|
|
Res := LazarusResources.Find('manifest');
|
|
if (Res <> nil) and (Res.Value <> '') and (Res.ValueType = 'RES') then
|
|
begin
|
|
Stream := nil;
|
|
try
|
|
Stream := TFileStream.Create(resFileName, fmCreate);
|
|
Stream.Write(Res.Value[1], length(Res.Value));
|
|
Result := True;
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectXPManifest.SetUseManifest(const AValue: boolean);
|
|
begin
|
|
FUseManifest := AValue;
|
|
end;
|
|
|
|
{-----------------------------------------------------------------------------
|
|
TProjectXPManifest UpdateMainSourceFile
|
|
-----------------------------------------------------------------------------}
|
|
function TProjectXPManifest.UpdateMainSourceFile(const AFilename: string): TModalResult;
|
|
var
|
|
NewX, NewY, NewTopLine: integer;
|
|
ManifestCodeBuf: TCodeBuffer;
|
|
CodePos: TCodeXYPosition;
|
|
begin
|
|
Result := mrCancel;
|
|
ManifestCodeBuf := CodeToolBoss.LoadFile(AFilename,false,false);
|
|
if ManifestCodeBuf <> nil then
|
|
begin
|
|
SetFileNames(AFilename);
|
|
if not CodeToolBoss.FindResourceDirective(ManifestCodeBuf, 1, 1,
|
|
ManifestCodeBuf, NewX, NewY,
|
|
NewTopLine, ExtractFileName(resFileName)) then
|
|
begin
|
|
if UseManifest then
|
|
begin
|
|
if not CodeToolBoss.AddResourceDirective(ManifestCodeBuf, ExtractFileName(resFileName)) then
|
|
begin
|
|
Messages.Add('Could not add "{$R'+ ExtractFileName(resFileName) +'"} to main source!');
|
|
exit;
|
|
end;
|
|
end;
|
|
end else
|
|
if not UseManifest then
|
|
begin
|
|
with CodeToolBoss.CurCodeTool do
|
|
begin
|
|
CodeToolBoss.SourceChangeCache.MainScanner := Scanner;
|
|
CodePos.Code := ManifestCodeBuf;
|
|
CodePos.X := NewX;
|
|
CodePos.Y := NewY;
|
|
CaretToCleanPos(CodePos, NewX);
|
|
if CodeToolBoss.SourceChangeCache.Replace(gtNone, gtNone, NewX, NewX + Length(ExtractFileName(resFileName)) + 5, '') then
|
|
begin
|
|
if not CodeToolBoss.SourceChangeCache.Apply then
|
|
exit;
|
|
end else
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
Result := mrOk;
|
|
end;
|
|
|
|
{-----------------------------------------------------------------------------
|
|
TProjectXPManifest SetFileNames
|
|
-----------------------------------------------------------------------------}
|
|
procedure TProjectXPManifest.SetFileNames(const MainFilename: string);
|
|
begin
|
|
resFilename := ExtractFilePath(MainFilename) + 'manifest.res';
|
|
end;
|
|
|
|
constructor TProjectXPManifest.Create;
|
|
begin
|
|
FMessages := TStringList.Create;
|
|
end;
|
|
|
|
destructor TProjectXPManifest.Destroy;
|
|
begin
|
|
FMessages.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
initialization
|
|
{$i manifest.lrs}
|
|
end.
|
|
|