Issue #140: Store application process id in each tabs.ini section, and don't restore tabs from other running processes. If the process no longer runs, restore such tab sections again, so nothing gets lost with multiple running application instances.

This commit is contained in:
Ansgar Becker
2019-04-13 10:43:52 +02:00
parent e9cc528632
commit a2ef1aeccd
2 changed files with 39 additions and 3 deletions

View File

@ -359,6 +359,7 @@ type
function DpiScaleFactor(Form: TForm): Double; function DpiScaleFactor(Form: TForm): Double;
function GetThemeColor(Color: TColor): TColor; function GetThemeColor(Color: TColor): TColor;
function ThemeIsDark(ThemeName: String): Boolean; function ThemeIsDark(ThemeName: String): Boolean;
function ProcessExists(pid: Cardinal): Boolean;
var var
AppSettings: TAppSettings; AppSettings: TAppSettings;
@ -3010,6 +3011,26 @@ begin
end; end;
function ProcessExists(pid: Cardinal): Boolean;
var
Proc: TProcessEntry32;
SnapShot: THandle;
ContinueLoop: Boolean;
begin
// Check if a given process id exists
SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
Proc.dwSize := Sizeof(Proc);
Result := False;
ContinueLoop := Process32First(SnapShot, Proc);
while ContinueLoop do begin
Result := Proc.th32ProcessID = pid;
if Result then
Break;
ContinueLoop := Process32Next(SnapShot, Proc);
end;
CloseHandle(Snapshot);
end;
{ Threading stuff } { Threading stuff }

View File

@ -2173,11 +2173,13 @@ begin
Section := Tab.Uid; Section := Tab.Uid;
if Tab.Memo.GetTextLen > 0 then begin if Tab.Memo.GetTextLen > 0 then begin
// Avoid writing the tabs.ini file through WriteString if nothing was effectively changed // Avoid writing the tabs.ini file if nothing was effectively changed
if TabsIni.ReadString(Section, 'BackupFilename', '') <> Tab.MemoBackupFilename then if TabsIni.ReadString(Section, 'BackupFilename', '') <> Tab.MemoBackupFilename then
TabsIni.WriteString(Section, 'BackupFilename', Tab.MemoBackupFilename); TabsIni.WriteString(Section, 'BackupFilename', Tab.MemoBackupFilename);
if TabsIni.ReadString(Section, 'Filename', '') <> Tab.MemoFilename then if TabsIni.ReadString(Section, 'Filename', '') <> Tab.MemoFilename then
TabsIni.WriteString(Section, 'Filename', Tab.MemoFilename); TabsIni.WriteString(Section, 'Filename', Tab.MemoFilename);
if TabsIni.ReadInteger(Section, 'pid', 0) <> Integer(GetCurrentProcessId) then
TabsIni.WriteInteger(Section, 'pid', Integer(GetCurrentProcessId));
end; end;
end; end;
@ -2197,6 +2199,7 @@ var
Sections: TStringList; Sections: TStringList;
Section, Filename, BackupFilename: String; Section, Filename, BackupFilename: String;
TabsIni: TIniFile; TabsIni: TIniFile;
pid: Cardinal;
begin begin
// Restore query tab setup from tabs.ini // Restore query tab setup from tabs.ini
@ -2206,9 +2209,19 @@ begin
Sections := TStringList.Create; Sections := TStringList.Create;
TabsIni.ReadSections(Sections); TabsIni.ReadSections(Sections);
for Section in Sections do begin for Section in Sections do begin
Filename := TabsIni.ReadString(Section, 'Filename', ''); Filename := TabsIni.ReadString(Section, 'Filename', '');
BackupFilename := TabsIni.ReadString(Section, 'BackupFilename', ''); BackupFilename := TabsIni.ReadString(Section, 'BackupFilename', '');
pid := Cardinal(TabsIni.ReadInteger(Section, 'pid', 0));
// Don't restore this tab if it belongs to a different running process
if (pid > 0) and (pid <> GetCurrentProcessId) and ProcessExists(pid) then
Continue;
// Either we have a backup file, or a user stored file.
// Both of them may not exist.
if not BackupFilename.IsEmpty then begin if not BackupFilename.IsEmpty then begin
if FileExists(BackupFilename) then begin if FileExists(BackupFilename) then begin
Tab := ActiveOrEmptyQueryTab(False); Tab := ActiveOrEmptyQueryTab(False);
@ -2217,7 +2230,7 @@ begin
Tab.MemoFilename := Filename; Tab.MemoFilename := Filename;
Tab.Memo.Modified := True; Tab.Memo.Modified := True;
end else begin end else begin
// Remove ini item if file is gone // Remove tab section if backup file is gone or inaccessible for some reason
TabsIni.EraseSection(Section); TabsIni.EraseSection(Section);
end; end;
end else if not Filename.IsEmpty then begin end else if not Filename.IsEmpty then begin
@ -2227,11 +2240,13 @@ begin
Tab.LoadContents(Filename, True, nil); Tab.LoadContents(Filename, True, nil);
Tab.MemoFilename := Filename; Tab.MemoFilename := Filename;
end else begin end else begin
// Remove ini item if file is gone // Remove tab section if user stored file was deleted by user
TabsIni.EraseSection(Section); TabsIni.EraseSection(Section);
end; end;
end; end;
end; end;
Sections.Free; Sections.Free;
// Close file // Close file
TabsIni.Free; TabsIni.Free;