diff --git a/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp b/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp index df77bb364..c5cc4e4c9 100644 --- a/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp +++ b/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp @@ -54,6 +54,7 @@ # define DAEMON_NAME L"/updatesvc.exe" # define DAEMON_NAME_OLD L"/~updatesvc.exe" # define RESTART_BATCH L"/svcrestart.bat" +# define UNINSTALL_LIST L"/unins000.bin" # define SUBFOLDER TEXT("/" REG_APP_NAME) # define ARCHIVE_EXT TEXT(".zip") # define ARCHIVE_PATTERN TEXT("*.zip") @@ -273,6 +274,37 @@ void CSvcManager::onCompleteUnzip(const int error) if (!NS_File::writeToFile(updPath + SUCCES_UNPACKED, successList)) { return; } +#ifdef _WIN32 + // Adding new app files to the uninstall list + auto fillSubpathVec = [](const tstring &path, vector &vec)->bool { + tstring _error; + list filesList; + if (!NS_File::GetFilesList(path, &filesList, _error)) { + NS_Logger::WriteLog(DEFAULT_ERROR_MESSAGE + TEXT(" ") + _error); + return false; + } + for (auto &filePath : filesList) { + tstring subPath = filePath.substr(path.length()); + vec.push_back(std::move(subPath)); + } + return true; + }; + + vector updVec, appVec; + const tstring appPath = NS_File::appPath(); + if (fillSubpathVec(appPath, appVec) && fillSubpathVec(updPath, updVec)) { + list delList; + if (NS_File::fileExists(appPath + UNINSTALL_LIST) && !NS_File::readBinFile(appPath + UNINSTALL_LIST, delList)) + NS_Logger::WriteLog(DEFAULT_ERROR_MESSAGE); + + for (auto &updFile : updVec) { + if (std::find(appVec.begin(), appVec.end(), updFile) == appVec.end()) + delList.push_back(NS_File::toNativeSeparators(updFile)); + } + if (!NS_File::writeToBinFile(updPath + UNINSTALL_LIST, delList)) + NS_Logger::WriteLog(DEFAULT_ERROR_MESSAGE); + } +#endif if (!m_socket->sendMessage(MSG_ShowStartInstallMessage)) NS_Logger::WriteLog(DEFAULT_ERROR_MESSAGE); diff --git a/win-linux/extras/update-daemon/src/platform_win/utils.cpp b/win-linux/extras/update-daemon/src/platform_win/utils.cpp index 3ecefe3a2..a87bcbbd2 100644 --- a/win-linux/extras/update-daemon/src/platform_win/utils.cpp +++ b/win-linux/extras/update-daemon/src/platform_win/utils.cpp @@ -178,6 +178,35 @@ namespace NS_File return true; } + bool readBinFile(const wstring &filePath, list &linesList) + { + std::ifstream file(filePath.c_str(), std::ios::in | std::ios::binary); + if (!file.is_open()) { + NS_Logger::WriteLog(L"An error occurred while opening: " + filePath); + return false; + } + while (file.peek() != EOF) { + WORD len = 0; + file.read((char*)(&len), sizeof(WORD)); + if (file.fail()) { + NS_Logger::WriteLog(L"An error occurred while reading: " + filePath); + file.close(); + return false; + } + wstring line; + line.resize(len); + file.read((char*)&line[0], len * sizeof(wchar_t)); + if (file.fail()) { + NS_Logger::WriteLog(L"An error occurred while reading: " + filePath); + file.close(); + return false; + } + linesList.push_back(std::move(line)); + } + file.close(); + return true; + } + bool writeToFile(const wstring &filePath, list &linesList) { std::wofstream file(filePath.c_str(), std::ios_base::out); @@ -192,6 +221,32 @@ namespace NS_File return true; } + bool writeToBinFile(const wstring &filePath, list &linesList) + { + std::ofstream file(filePath.c_str(), std::ios::binary | std::ios::app); + if (!file.is_open()) { + NS_Logger::WriteLog(L"An error occurred while writing: " + filePath); + return false; + } + for (auto &line : linesList) { + WORD len = line.length(); + file.write((const char*)&len, sizeof(WORD)); + if (file.fail()) { + NS_Logger::WriteLog(L"An error occurred while writing: " + filePath); + file.close(); + return false; + } + file.write((const char*)line.c_str(), len * sizeof(wchar_t)); + if (file.fail()) { + NS_Logger::WriteLog(L"An error occurred while writing: " + filePath); + file.close(); + return false; + } + } + file.close(); + return true; + } + bool runProcess(const wstring &fileName, const wstring &args) { if (NS_Utils::isRunAsApp()) { diff --git a/win-linux/extras/update-daemon/src/platform_win/utils.h b/win-linux/extras/update-daemon/src/platform_win/utils.h index 56849ef13..94ccd1817 100644 --- a/win-linux/extras/update-daemon/src/platform_win/utils.h +++ b/win-linux/extras/update-daemon/src/platform_win/utils.h @@ -58,7 +58,9 @@ namespace NS_File { bool GetFilesList(const wstring &path, list *lst, wstring &error, bool ignore_locked = false, bool folders_only = false); bool readFile(const wstring &filePath, list &linesList); +bool readBinFile(const wstring &filePath, list &linesList); bool writeToFile(const wstring &filePath, list &linesList); +bool writeToBinFile(const wstring &filePath, list &linesList); bool runProcess(const wstring &fileName, const wstring &args); bool isProcessRunning(const wstring &fileName); bool fileExists(const wstring &filePath); diff --git a/win-linux/package/windows/common.iss b/win-linux/package/windows/common.iss index e1fc4d1a9..1ed1abcbc 100644 --- a/win-linux/package/windows/common.iss +++ b/win-linux/package/windows/common.iss @@ -787,7 +787,7 @@ begin UnassociateExtensions(); end else if CurUninstallStep = usPostUninstall then begin - + RemoveExtraFiles(); end; end; @@ -1051,3 +1051,4 @@ Type: filesandordirs; Name: {commonappdata}\{#APP_PATH}\*; AfterInstall: Refres Type: files; Name: "{app}\new_word.bat"; Type: files; Name: "{app}\new_cell.bat"; Type: files; Name: "{app}\new_slide.bat"; +Type: files; Name: "{app}\svcrestart.bat"; diff --git a/win-linux/package/windows/utils.iss b/win-linux/package/windows/utils.iss index 353010185..a7721c926 100644 --- a/win-linux/package/windows/utils.iss +++ b/win-linux/package/windows/utils.iss @@ -119,3 +119,65 @@ begin SaveStringsToFile(fileName, lines, False); end; end; + +function ReadBinFile(fileName: String; list: TStringList): Boolean; +var + fs: TFileStream; + buff: String; + len: Word; + ch: Char; +begin + Result := False; + if not FileExists(fileName) then + Exit; + list.Clear; + try + fs := TFileStream.Create(fileName, fmOpenRead); + except + Exit; + end; + while fs.Position < fs.Size do begin + SetLength(buff, 1); + try + fs.ReadBuffer(buff, SizeOf(len)); + except + fs.Free; + Exit; + end; + len := Ord(buff[1]); + SetLength(buff, len); + try + fs.ReadBuffer(buff, len * SizeOf(ch)); + except + fs.Free; + Exit; + end; + list.Add(buff); + end; + Result := True; + fs.Free; +end; + +procedure RemoveExtraFiles(); +var + i: Integer; + appPath, path: String; + files: TStringList; +begin + files := TStringList.Create; + appPath := ExpandConstant('{app}'); + if ReadBinFile(appPath + '\unins000.bin', files) then begin + for i := 0 to files.Count - 1 do begin + if DeleteFile(appPath + files[i]) then begin + path := ExtractFileDir(files[i]); + while (path <> '\') do begin + if not RemoveDir(appPath + path) then + break; + path := ExtractFileDir(path); + end; + end; + end; + end; + files.Free; + DeleteFile(appPath + '\unins000.bin'); +end;