diff --git a/extra/SetVersion/SetVersion.dpr b/extra/SetVersion/SetVersion.dpr
new file mode 100644
index 00000000..fbaa843a
--- /dev/null
+++ b/extra/SetVersion/SetVersion.dpr
@@ -0,0 +1,164 @@
+program SetVersion;
+
+{$APPTYPE CONSOLE}
+
+uses
+ SysUtils, Windows, SynRegExpr, Classes;
+
+var
+ FileName, FileContent, Line, Revision, CurDir, SvnOutput, Cmd: String;
+ FileHandle: TextFile;
+ rx: TRegExpr;
+ SvnOutputLines: TStringList;
+
+
+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)';
+ FileContent := rx.Replace(FileContent, '${1}'+Revision+'${2}', True);
+ rx.Free;
+
+ // Save modified file
+ Rewrite(FileHandle);
+ WriteLn(FileHandle, FileContent);
+ CloseFile(FileHandle);
+ except
+ on E: Exception do
+ Writeln(E.ClassName, ': ', E.Message);
+ end;
+
+end.
+
diff --git a/extra/SetVersion/SetVersion.dproj b/extra/SetVersion/SetVersion.dproj
new file mode 100644
index 00000000..57e987b1
--- /dev/null
+++ b/extra/SetVersion/SetVersion.dproj
@@ -0,0 +1,107 @@
+
+
+ {2E249C21-5A3E-430F-AC5A-E8BAAF56C3FC}
+ 12.0
+ SetVersion.dpr
+ Debug
+ DCC32
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ SetVersion.exe
+ 00400000
+ false
+ WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)
+ x86
+ false
+ 0
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ false
+
+
+ DEBUG;$(DCC_Define)
+
+
+
+ MainSource
+
+
+ Base
+
+
+ Cfg_2
+ Base
+
+
+ Cfg_1
+ Base
+
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ SetVersion.dpr
+
+
+ False
+ True
+ False
+
+
+ False
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1031
+ 1252
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+
+ 12
+
+
diff --git a/extra/SetVersion/SetVersion.exe b/extra/SetVersion/SetVersion.exe
new file mode 100644
index 00000000..067e31a7
Binary files /dev/null and b/extra/SetVersion/SetVersion.exe differ
diff --git a/extra/build_everything.cmd b/extra/build_everything.cmd
index ba8e8e89..f9a4e825 100644
--- a/extra/build_everything.cmd
+++ b/extra/build_everything.cmd
@@ -25,7 +25,7 @@ echo.
:test_dcc32
dcc32.exe --version >NUL: 2>NUL:
-if %errorlevel% == 0 goto test_svn
+if %errorlevel% == 0 goto test_libs
:dcc32_not_found
echo Error: Delphi compiler 'dcc32.exe' was not found in PATH.
@@ -39,22 +39,6 @@ echo.
pause > NUL:
goto :eof
-:test_svn
-svnversion.exe --version >NUL: 2>NUL:
-if %errorlevel% == 0 goto test_libs
-
-:svn_not_found
-echo Error: Subversion executable 'svnversion.exe' was not found in PATH.
-echo.
-echo Please install Subversion. When installing, Subversion should modify
-echo your system path to include the location of this file.
-echo.
-echo See also:
-echo http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91^&filter=setup.exe
-echo.
-pause > NUL:
-goto :eof
-
:locate_dcc32
if not "%compiler_dir%" == "none" goto :eof
pushd %~f1
@@ -124,34 +108,8 @@ goto param_loop
:param_done
echo Base directory: %base_dir%
echo Compiler directory: %compiler_dir%
-
-:find_wcver
-rem Unix tool, may not handle Windows paths well, so go to base directory and use dot.
-cd /d "%base_dir%"
-for /f "usebackq" %%s in (`svnversion.exe . ^|^| ECHO unknown`) DO SET wcver=WC %%s
-if "%wcver%" == "WC unknown" (set wcver=unknown) else (goto insert_wcver)
-
-:svnversion_failure
-rem Non-fatal, continue if this happens.
-echo.
-echo Error: svnversion failed - run this step manually to see what went wrong?
-echo.
-
-:insert_wcver
-echo Version: %WCVER%
-echo.
-rem Put WC version or "unknown" into main.pas
-"%base_dir%\extra\sed\sed.exe" "s/\$Revision.*\$/\$Revision: %WCVER% \$/g" -i "%base_dir%\source\main.pas"
-if not %errorlevel% == 0 goto sedfail
-"%base_dir%\extra\sed\sed.exe" "s/\$Rev[^i].*\$/\$Rev: %WCVER% \$/g" -i "%base_dir%\source\main.pas"
-if not %errorlevel% == 0 goto sedfail
goto start
-:sedfail
-echo Error: SED failure - run this step manually to see what went wrong?
-echo.
-goto end
-
:start
rem Delete old binaries
echo Cleaning build directories.
@@ -198,6 +156,7 @@ if not %err% == 0 goto end
rem Build main executable
echo Compiling main project.
cd /d "%base_dir%\packages\%package_dir%\"
+..\..\extra\SetVersion\SetVersion.exe ..\..\res\version.rc
brcc32 ..\..\res\version.rc
brcc32 ..\..\res\icon.rc
brcc32 ..\..\res\manifest.rc
diff --git a/extra/sed/libiconv2.dll b/extra/sed/libiconv2.dll
deleted file mode 100644
index 747073f1..00000000
Binary files a/extra/sed/libiconv2.dll and /dev/null differ
diff --git a/extra/sed/libintl3.dll b/extra/sed/libintl3.dll
deleted file mode 100644
index ec11e6b1..00000000
Binary files a/extra/sed/libintl3.dll and /dev/null differ
diff --git a/extra/sed/sed.exe b/extra/sed/sed.exe
deleted file mode 100644
index 6a1f9fd0..00000000
Binary files a/extra/sed/sed.exe and /dev/null differ
diff --git a/packages/delphi2010/heidisql.dproj b/packages/delphi2010/heidisql.dproj
index c03e63a5..6a9432a0 100644
--- a/packages/delphi2010/heidisql.dproj
+++ b/packages/delphi2010/heidisql.dproj
@@ -47,6 +47,7 @@
False
+ ..\..\res
3
..\..\out\heidisql.exe
7.0
diff --git a/source/about.pas b/source/about.pas
index 57e24516..52c7464d 100644
--- a/source/about.pas
+++ b/source/about.pas
@@ -100,7 +100,7 @@ begin
MemoAuthors.Text := TrimRight(MemoAuthors.Text);
// App-Version
- LabelVersion.Caption := FullAppVersion;
+ LabelVersion.Caption := 'Version '+AppVersion;
// Compile-date
FileAge(ParamStr(0), Compiled);
diff --git a/source/helpers.pas b/source/helpers.pas
index bd90331f..a6cc654d 100644
--- a/source/helpers.pas
+++ b/source/helpers.pas
@@ -846,7 +846,7 @@ begin
else
NodeCount := Grid.RootNodeCount;
EnableProgressBar(NodeCount);
- Generator := APPNAME+' '+FullAppVersion;
+ Generator := APPNAME+' '+AppVersion;
tmp :=
'' + CRLF + CRLF +
diff --git a/source/main.pas b/source/main.pas
index d2610f9c..272eded2 100644
--- a/source/main.pas
+++ b/source/main.pas
@@ -864,9 +864,8 @@ end;
var
MainForm : TMainForm;
- AppVersion : String = '4.0';
- AppRevision : String = '$Rev$';
- FullAppVersion : String;
+ AppVerMajor, AppVerMinor, AppVerRelease, AppVerRevision: Integer;
+ AppVersion : String;
DirnameCommonAppData,
DirnameUserAppData,
DirnameSnippets,
@@ -1143,6 +1142,11 @@ var
DisableProcessWindowsGhostingProc: procedure;
QueryTab: TQueryTab;
Action: TAction;
+ dwInfoSize, // Size of VERSIONINFO structure
+ dwVerSize, // Size of Version Info Data
+ dwWnd: DWORD; // Handle for the size call.
+ FI: PVSFixedFileInfo; // Delphi structure; see WINDOWS.PAS
+ ptrVerBuf: Pointer; // pointer to a version buffer
begin
caption := APPNAME;
setLocales;
@@ -1156,16 +1160,17 @@ begin
refreshMonitorConfig;
loadWindowConfig;
- // Beautify AppRevision
- if Pos('$Rev: WC', AppRevision) < 1 then
- AppRevision := 'unknown'
- else begin
- AppRevision := StringReplace( AppRevision, '$Rev: WC', '', [rfIgnoreCase] );
- AppRevision := StringReplace( AppRevision, '$', '', [] );
- AppRevision := Trim( AppRevision );
- end;
- // Compose full version string
- FullAppVersion := 'Version ' + AppVersion + ', Revision ' + AppRevision;
+ // Detect version
+ dwInfoSize := GetFileVersionInfoSize(PChar(Application.ExeName), dwWnd);
+ GetMem(ptrVerBuf, dwInfoSize);
+ GetFileVersionInfo(PChar(Application.ExeName), dwWnd, dwInfoSize, ptrVerBuf);
+ VerQueryValue(ptrVerBuf, '\', Pointer(FI), dwVerSize );
+ AppVerMajor := HiWord(FI.dwFileVersionMS);
+ AppVerMinor := LoWord(FI.dwFileVersionMS);
+ AppVerRelease := HiWord(FI.dwFileVersionLS);
+ AppVerRevision := LoWord(FI.dwFileVersionLS);
+ FreeMem(ptrVerBuf);
+ AppVersion := Format('%d.%d.%d.%d', [AppVerMajor, AppVerMinor, AppVerRelease, AppVerRevision]);
// "All users" folder for HeidiSQL's data (All Users\Application Data)
DirnameCommonAppData := GetShellFolder(CSIDL_COMMON_APPDATA) + '\' + APPNAME + '\';
@@ -1394,7 +1399,7 @@ begin
end;
if DaysBetween(Now, LastStatsCall) >= 30 then begin
// Report used SVN revision
- StatsURL := APPDOMAIN + 'savestats.php?c=' + AppRevision;
+ StatsURL := APPDOMAIN + 'savestats.php?c=' + IntToStr(AppVerRevision);
// Enumerate actively used server versions
SessionNames := TStringlist.Create;
if MainReg.OpenKey(REGPATH + REGKEY_SESSIONS, true) then
@@ -1411,7 +1416,7 @@ begin
end;
StatsCall := TDownloadUrl2.Create(Self);
StatsCall.URL := StatsURL;
- StatsCall.SetUserAgent(APPNAME + ' ' + FullAppVersion);
+ StatsCall.SetUserAgent(APPNAME + ' ' + AppVersion);
try
StatsCall.ExecuteTarget(nil);
OpenRegistry;
@@ -8488,7 +8493,7 @@ begin
Cap := Cap + ' /' + ActiveDatabase;
if SelectedTable.Name <> '' then
Cap := Cap + '/' + SelectedTable.Name;
- Cap := Cap + ' - ' + APPNAME + ' ' + FullAppVersion;
+ Cap := Cap + ' - ' + APPNAME + ' ' + AppVersion;
Caption := Cap;
Application.Title := Cap;
end;
diff --git a/source/tabletools.pas b/source/tabletools.pas
index b056996f..458869f7 100644
--- a/source/tabletools.pas
+++ b/source/tabletools.pas
@@ -961,7 +961,7 @@ begin
WideFormat('# %-30s%s', ['Database:', DBObj.Database]) + CRLF +
WideFormat('# %-30s%s', ['Server version:', Mainform.Connection.ServerVersionUntouched]) + CRLF +
WideFormat('# %-30s%s', ['Server OS:', Mainform.Connection.GetVar('SHOW VARIABLES LIKE ' + esc('version_compile_os'), 1)]) + CRLF +
- WideFormat('# %-30s%s', [APPNAME + ' version:', FullAppVersion]) + CRLF +
+ WideFormat('# %-30s%s', [APPNAME + ' version:', AppVersion]) + CRLF +
WideFormat('# %-30s%s', ['Date/time:', DateTimeToStr(Now)]) + CRLF +
'# --------------------------------------------------------' + CRLF + CRLF +
'/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;' + CRLF +
diff --git a/source/updatecheck.pas b/source/updatecheck.pas
index c25b5c36..a9a0a88c 100644
--- a/source/updatecheck.pas
+++ b/source/updatecheck.pas
@@ -37,7 +37,7 @@ type
public
{ Public declarations }
AutoClose: Boolean; // Automatically close dialog after detecting no available downloads
- CurrentRevision, BuildRevision: Integer;
+ BuildRevision: Integer;
CheckForBuildsInAutoMode: Boolean;
BuildSize: Integer;
end;
@@ -95,7 +95,6 @@ procedure TfrmUpdateCheck.FormShow(Sender: TObject);
begin
Status('Initiating ... ');
Caption := 'Check for '+APPNAME+' updates ...';
- CurrentRevision := StrToIntDef(AppRevision, 0);
// Init GUI controls
btnRelease.Enabled := False;
@@ -105,8 +104,8 @@ begin
// Prepare download
CheckfileDownload := TDownLoadURL2.Create(Self);
- CheckfileDownload.SetUserAgent(APPNAME + ' ' + APPVERSION + ' ' + APPREVISION + ' update checker tool');
- CheckfileDownload.URL := APPDOMAIN + 'updatecheck.php?r='+APPREVISION;
+ CheckfileDownload.SetUserAgent(APPNAME + ' ' + AppVersion + ' update checker tool');
+ CheckfileDownload.URL := APPDOMAIN + 'updatecheck.php?r='+IntToStr(AppVerRevision);
CheckfileDownload.Filename := GetTempDir + APPNAME + '_updatecheck.ini';
// Download the check file
@@ -118,9 +117,9 @@ begin
ReadCheckFile;
// Developer versions probably have "unknown" (0) as revision,
// which makes it impossible to compare the revisions.
- if CurrentRevision = 0 then
+ if AppVerRevision = 0 then
Status('Error: Cannot determine current revision. Using a developer version?')
- else if CurrentRevision = BuildRevision then
+ else if AppVerRevision = BuildRevision then
Status('Your '+APPNAME+' is up-to-date (no update available).')
else if groupRelease.Enabled or btnBuild.Enabled then
Status('Updates available.');
@@ -174,7 +173,7 @@ begin
memoRelease.Lines.Add( 'Note: ' + Note );
btnRelease.Caption := 'Download version ' + ReleaseVersion;
// Enable the download button if the current version is outdated
- groupRelease.Enabled := ReleaseRevision > CurrentRevision;
+ groupRelease.Enabled := ReleaseRevision > AppVerRevision;
btnRelease.Enabled := groupRelease.Enabled;
memoRelease.Enabled := groupRelease.Enabled;
if not memoRelease.Enabled then
@@ -188,7 +187,7 @@ begin
BuildRevision := Ini.ReadInteger(INISECT_BUILD, 'Revision', 0);
BuildURL := Ini.ReadString(INISECT_BUILD, 'URL', '');
BuildSize := Ini.ReadInteger(INISECT_BUILD, 'Size', 0);
- memoBuild.Lines.Add( 'Revision ' + IntToStr(BuildRevision) + ' (yours: '+AppRevision+')' );
+ memoBuild.Lines.Add( 'Revision ' + IntToStr(BuildRevision) + ' (yours: '+IntToStr(AppVerRevision)+')' );
FileAge(ParamStr(0), Compiled);
memoBuild.Lines.Add( 'Compiled: ' + Ini.ReadString(INISECT_BUILD, 'Date', '') + ' (yours: '+DateToStr(Compiled)+')' );
Note := Ini.ReadString(INISECT_BUILD, 'Note', '');
@@ -198,7 +197,7 @@ begin
// A new release should have priority over a new nightly build.
// So the user should not be able to download a newer build here
// before having installed the new release.
- btnBuild.Enabled := (CurrentRevision = 0) or ((BuildRevision > CurrentRevision) and (not btnRelease.Enabled));
+ btnBuild.Enabled := (AppVerRevision = 0) or ((BuildRevision > AppVerRevision) and (not btnRelease.Enabled));
end;
end;