diff --git a/res/msi/CustomActions/Common.h b/res/msi/CustomActions/Common.h index 08302d98c..bc9ed1ad9 100644 --- a/res/msi/CustomActions/Common.h +++ b/res/msi/CustomActions/Common.h @@ -18,6 +18,9 @@ void UninstallDriver(LPCWSTR hardwareId, BOOL &rebootRequired); namespace RemotePrinter { - VOID installUpdatePrinter(const std::wstring& installFolder); - VOID uninstallPrinter(); + // `appName` names the printer and its port. It is passed in rather than compiled + // in so that a single dll serves every custom client; an empty value keeps the + // stock "RustDesk Printer" name. + VOID installUpdatePrinter(const std::wstring& installFolder, const std::wstring& appName); + VOID uninstallPrinter(const std::wstring& appName); } diff --git a/res/msi/CustomActions/CustomActions.cpp b/res/msi/CustomActions/CustomActions.cpp index f4780dd87..f53a910a9 100644 --- a/res/msi/CustomActions/CustomActions.cpp +++ b/res/msi/CustomActions/CustomActions.cpp @@ -1022,6 +1022,7 @@ UINT __stdcall InstallPrinter( int nResult = 0; LPWSTR installFolder = NULL; + LPWSTR appName = NULL; LPWSTR pwz = NULL; LPWSTR pwzData = NULL; @@ -1035,11 +1036,21 @@ UINT __stdcall InstallPrinter( hr = WcaReadStringFromCaData(&pwz, &installFolder); ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz); + // Names the printer. Optional, so that a package built before this was passed in + // still installs, keeping the stock printer name. + if (FAILED(WcaReadStringFromCaData(&pwz, &appName))) + { + ReleaseNullStr(appName); + } + WcaLog(LOGMSG_STANDARD, "Try to install RD printer in : %ls", installFolder); - RemotePrinter::installUpdatePrinter(installFolder); + RemotePrinter::installUpdatePrinter(installFolder, appName ? appName : L""); WcaLog(LOGMSG_STANDARD, "Install RD printer done"); LExit: + if (appName) { + ReleaseStr(appName); + } if (pwzData) { ReleaseStr(pwzData); } @@ -1054,14 +1065,36 @@ UINT __stdcall UninstallPrinter( HRESULT hr = S_OK; DWORD er = ERROR_SUCCESS; + LPWSTR appName = NULL; + LPWSTR pwz = NULL; + LPWSTR pwzData = NULL; + hr = WcaInitialize(hInstall, "UninstallPrinter"); ExitOnFailure(hr, "Failed to initialize"); + // Must match the name install used, otherwise the printer is left behind. Absent + // on packages built before this was passed in, where it was the stock name. + if (SUCCEEDED(WcaGetProperty(L"CustomActionData", &pwzData))) + { + pwz = pwzData; + if (FAILED(WcaReadStringFromCaData(&pwz, &appName))) + { + ReleaseNullStr(appName); + } + } + WcaLog(LOGMSG_STANDARD, "Try to uninstall RD printer"); - RemotePrinter::uninstallPrinter(); + RemotePrinter::uninstallPrinter(appName ? appName : L""); WcaLog(LOGMSG_STANDARD, "Uninstall RD printer done"); LExit: + if (appName) { + ReleaseStr(appName); + } + if (pwzData) { + ReleaseStr(pwzData); + } + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); } diff --git a/res/msi/CustomActions/RemotePrinter.cpp b/res/msi/CustomActions/RemotePrinter.cpp index 767c8c82c..532a3524b 100644 --- a/res/msi/CustomActions/RemotePrinter.cpp +++ b/res/msi/CustomActions/RemotePrinter.cpp @@ -18,12 +18,19 @@ namespace RemotePrinter { #define HRESULT_ERR_ELEMENT_NOT_FOUND 0x80070490 + // The driver files and the driver name ship with the app under their stock names + // and stay fixed for every custom client. Only the printer and its port carry the + // app name, and that arrives at runtime so one dll serves every custom client. LPCWCH RD_DRIVER_INF_PATH = L"drivers\\RustDeskPrinterDriver\\RustDeskPrinterDriver.inf"; - LPCWCH RD_PRINTER_PORT = L"RustDesk Printer"; - LPCWCH RD_PRINTER_NAME = L"RustDesk Printer"; LPCWCH RD_PRINTER_DRIVER_NAME = L"RustDesk v4 Printer Driver"; + LPCWCH RD_DEFAULT_APP_NAME = L"RustDesk"; LPCWCH XCV_MONITOR_LOCAL_PORT = L",XcvMonitor Local Port"; + static std::wstring printerNameOf(const std::wstring &appName) + { + return (appName.empty() ? std::wstring(RD_DEFAULT_APP_NAME) : appName) + L" Printer"; + } + using FuncEnum = std::function; template using FuncOnData = std::function(const T &)>; @@ -458,8 +465,12 @@ namespace RemotePrinter // We should not check the driver version because the driver is deployed with the application. // It's better to uninstall the existing driver and install the driver from the application. // 3. Add the printer. - VOID installUpdatePrinter(const std::wstring &installFolder) + VOID installUpdatePrinter(const std::wstring &installFolder, const std::wstring &appName) { + const std::wstring printerName = printerNameOf(appName); + const LPCWCH RD_PRINTER_NAME = printerName.c_str(); + const LPCWCH RD_PRINTER_PORT = printerName.c_str(); + const std::wstring infFile = installFolder + L"\\" + RemotePrinter::RD_DRIVER_INF_PATH; if (!FileExists(infFile)) { @@ -505,13 +516,15 @@ namespace RemotePrinter } } - VOID uninstallPrinter() + VOID uninstallPrinter(const std::wstring &appName) { - deletePrinter(RD_PRINTER_NAME); + const std::wstring printerName = printerNameOf(appName); + + deletePrinter(printerName.c_str()); WcaLog(LOGMSG_STANDARD, "Deleted the printer\n"); uninstallDriver(RD_PRINTER_DRIVER_NAME); WcaLog(LOGMSG_STANDARD, "Uninstalled the printer driver\n"); - checkDeleteLocalPort(RD_PRINTER_PORT); + checkDeleteLocalPort(printerName.c_str()); WcaLog(LOGMSG_STANDARD, "Deleted the local port\n"); } } diff --git a/res/msi/Package/Components/RustDesk.wxs b/res/msi/Package/Components/RustDesk.wxs index 5ca5364a7..3e77e76d1 100644 --- a/res/msi/Package/Components/RustDesk.wxs +++ b/res/msi/Package/Components/RustDesk.wxs @@ -30,7 +30,10 @@ - + + + @@ -86,6 +89,7 @@ + diff --git a/res/msi/preprocess.py b/res/msi/preprocess.py index ff0b5f510..3f52aceb8 100644 --- a/res/msi/preprocess.py +++ b/res/msi/preprocess.py @@ -10,7 +10,6 @@ import subprocess import re import platform from pathlib import Path -from itertools import chain import shutil g_indent_unit = "\t" @@ -189,18 +188,6 @@ def replace_app_name_in_langs(app_name): with open(file_path, "w", encoding="utf-8") as f: f.writelines(lines) -def replace_app_name_in_custom_actions(app_name): - custion_actions_dir = Path(sys.argv[0]).parent.joinpath("CustomActions") - for file_path in chain(custion_actions_dir.glob("*.cpp"), custion_actions_dir.glob("*.h")): - with open(file_path, "r", encoding="utf-8") as f: - lines = f.readlines() - for i, line in enumerate(lines): - line = re.sub(r"\bRustDesk\b", app_name, line) - line = line.replace(f"{app_name} v4 Printer Driver", "RustDesk v4 Printer Driver") - lines[i] = line - with open(file_path, "w", encoding="utf-8") as f: - f.writelines(lines) - def gen_upgrade_info(): def func(lines, index_start): indent = g_indent_unit * 3 @@ -557,4 +544,3 @@ if __name__ == "__main__": sys.exit(-1) replace_app_name_in_langs(args.app_name) - replace_app_name_in_custom_actions(args.app_name)