Files
HeidiSQL/extra/SetVersion/SetVersion.dpr

173 lines
4.7 KiB
ObjectPascal

program SetVersion;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, SynRegExpr, Classes;
var
FileName, FileContent, Line, Revision, AppVer, CurDir, SvnOutput, Cmd: String;
FileHandle: TextFile;
rx: TRegExpr;
SvnOutputLines: TStringList;
{$I ..\..\source\const.inc}
function RunConsoleAppWaitAndCapture(const cConsoleApp, cParameters,
cWorkingDir: string; aResults: TStringList): DWord;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
hStdOut, hAppProcess, hAppThread: THandle;
cTemp, cTempFile: String;
aBuffer: Array[0..255] of Char;
begin
Result := 0;
hAppProcess := 0;
hAppThread := 0;
aResults.Clear;
GetTempPath( 255, aBuffer );
cTemp := StrPas( aBuffer );
cTempFile := cTemp + 'stdout.tmp';
if FileExists(cTempFile) then
SysUtils.DeleteFile( cTempFile );
// Initialize output file security attributes
FillChar(SA, SizeOf(SA), #0 );
SA.nLength := SizeOf(SA);
SA.lpSecurityDescriptor := nil;
SA.bInheritHandle := true;
// Create Output File
hStdOut := CreateFile(PChar(cTempFile),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
@SA,
CREATE_ALWAYS, // Always create it
FILE_ATTRIBUTE_TEMPORARY or // Will cache in memory if possible
FILE_FLAG_WRITE_THROUGH,
0);
if hStdOut = INVALID_HANDLE_VALUE then begin
ExitCode := 103;
Raise Exception.CreateFmt('Creating temporary stdout "'+cTempFile+'" file failed.', [cConsoleApp]);
end;
// Initialize Startup Info
FillChar(SI, SizeOf(SI), #0);
with SI do begin
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE);
hStdError := hStdOut;
hStdOutput := hStdOut;
end;
try
// Create the process
cTemp := cConsoleApp + ' ' + cParameters;
if CreateProcess(nil,
PChar( cTemp ),
nil,
nil,
true,
0,
nil,
PChar(cWorkingDir),
SI,
PI
) then begin
WaitforSingleObject( PI.hProcess, INFINITE );
hAppProcess := PI.hProcess;
hAppThread := PI.hThread;
GetExitCodeProcess( hAppProcess, result );
end else begin
ExitCode := 104;
Raise Exception.CreateFmt('CreateProcess() failed!'#10#13'Command line = %s', [cConsoleApp]);
end;
CloseHandle( hStdOut );
if FileExists(cTempFile) then begin
try
aResults.LoadFromFile(cTempFile);
except
on e:Exception do
WriteLn(e.Message);
end;
SysUtils.DeleteFile(cTempFile);
end;
finally
if hAppProcess <> 0 then
CloseHandle(hAppProcess);
if hAppThread <> 0 then
CloseHandle(hAppThread);
end;
end;
begin
try
FileName := Paramstr(1);
if not FileExists(FileName) then begin
raise Exception.Create('File "'+FileName+'" is not a valid resource file.');
ExitCode := 101;
end;
// Read resource file
AssignFile(FileHandle, FileName);
Reset(FileHandle);
while not Eof(FileHandle) do begin
ReadLn(FileHandle, Line);
FileContent := FileContent + Line + #13#10;
end;
Delete(FileContent, Length(FileContent)-1, 2);
CloseFile(FileHandle);
// Regular expression object
rx := TRegExpr.Create;
rx.ModifierI := True;
// Find Subversion revision number
CurDir := ExtractFilePath(paramStr(0));
SvnOutputLines := TStringList.Create;
Cmd := 'svnversion.exe';
RunConsoleAppWaitAndCapture(Cmd, ExtractFilePath(ExpandFileName(FileName)), CurDir, SvnOutputLines);
SvnOutput := Trim(SvnOutputLines.Text);
// 123:123M
// 123M
// 123
rx.Expression := '^(\d+\:)?(\d+)M?$';
if rx.Exec(SvnOutput) then
Revision := rx.Match[2]
else begin
ExitCode := 102;
raise Exception.Create('Could not find SVN revision');
end;
// Inject revision into file content
rx.Expression := '((\bFILEVERSION\s)(\d+),(\d+),(\d+),)\d+(\b)';
if rx.Exec(FileContent) then
AppVer := rx.Match[3]+'.'+rx.Match[4]+'.'+rx.Match[5]+'.'+Revision
else
AppVer := '[Parse error in '+ExtractFileName(ParamStr(0))+']';
FileContent := rx.Replace(FileContent, '${1}'+Revision+'${6}', True);
rx.Free;
FileContent := StringReplace(FileContent, '%APPNAME%', APPNAME, [rfReplaceAll]);
FileContent := StringReplace(FileContent, '%APPVER%', AppVer, [rfReplaceAll]);
// Save modified file
Rewrite(FileHandle);
WriteLn(FileHandle, FileContent);
CloseFile(FileHandle);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.