mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-14 01:56:36 +08:00
173 lines
4.7 KiB
ObjectPascal
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.
|
|
|