Fix. Msi. Terminate brokers. (#7693)
* Fix. Msi. Terminate brokers. Signed-off-by: fufesou <shuanglongchen@yeah.net> * Fix. Msi, remove tray shortcut in startmenu Signed-off-by: fufesou <shuanglongchen@yeah.net> * Msi. format Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi, set property Signed-off-by: fufesou <shuanglongchen@yeah.net> * Fix. Mis, only do InstallValidate if is Install Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
98df2b111e
commit
8231d07706
15
res/msi/CustomActions/Common.h
Normal file
15
res/msi/CustomActions/Common.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
bool AddFirewallRule(bool add, LPWSTR exeName, LPWSTR exeFile);
|
||||||
|
|
||||||
|
bool IsServiceRunningW(LPCWSTR serviceName);
|
||||||
|
bool MyCreateServiceW(LPCWSTR serviceName, LPCWSTR displayName, LPCWSTR binaryPath);
|
||||||
|
bool MyDeleteServiceW(LPCWSTR serviceName);
|
||||||
|
bool MyStartServiceW(LPCWSTR serviceName);
|
||||||
|
bool MyStopServiceW(LPCWSTR serviceName);
|
||||||
|
|
||||||
|
std::wstring ReadConfig(const std::wstring& filename, const std::wstring& key);
|
||||||
|
|
@ -8,6 +8,8 @@
|
|||||||
#include <netfw.h>
|
#include <netfw.h>
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
|
||||||
|
#include "./Common.h"
|
||||||
|
|
||||||
#pragma comment(lib, "Shlwapi.lib")
|
#pragma comment(lib, "Shlwapi.lib")
|
||||||
|
|
||||||
UINT __stdcall CustomActionHello(
|
UINT __stdcall CustomActionHello(
|
||||||
@ -271,7 +273,6 @@ void RemoveFirewallRuleCmdline(LPWSTR exeName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddFirewallRule(bool add, LPWSTR exeName, LPWSTR exeFile);
|
|
||||||
UINT __stdcall AddFirewallRules(
|
UINT __stdcall AddFirewallRules(
|
||||||
__in MSIHANDLE hInstall)
|
__in MSIHANDLE hInstall)
|
||||||
{
|
{
|
||||||
@ -323,3 +324,220 @@ LExit:
|
|||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT __stdcall SetPropertyIsServiceRunning(__in MSIHANDLE hInstall)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD er = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
wchar_t szAppName[500] = { 0 };
|
||||||
|
DWORD cchAppName = sizeof(szAppName) / sizeof(szAppName[0]);
|
||||||
|
wchar_t szPropertyName[500] = { 0 };
|
||||||
|
DWORD cchPropertyName = sizeof(szPropertyName) / sizeof(szPropertyName[0]);
|
||||||
|
bool isRunning = false;
|
||||||
|
|
||||||
|
hr = WcaInitialize(hInstall, "SetPropertyIsServiceRunning");
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"AppName", szAppName, &cchAppName);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try query service of : \"%ls\"", szAppName);
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"PropertyName", szPropertyName, &cchPropertyName);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try set is service running, property name : \"%ls\"", szPropertyName);
|
||||||
|
|
||||||
|
isRunning = IsServiceRunningW(szAppName);
|
||||||
|
MsiSetPropertyW(hInstall, szPropertyName, isRunning ? L"'N'" : L"'Y'");
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(er);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT __stdcall CreateStartService(__in MSIHANDLE hInstall)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD er = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
LPWSTR svcParams = NULL;
|
||||||
|
LPWSTR pwz = NULL;
|
||||||
|
LPWSTR pwzData = NULL;
|
||||||
|
LPWSTR svcName = NULL;
|
||||||
|
LPWSTR svcBinary = NULL;
|
||||||
|
wchar_t szSvcDisplayName[500] = { 0 };
|
||||||
|
DWORD cchSvcDisplayName = sizeof(szSvcDisplayName) / sizeof(szSvcDisplayName[0]);
|
||||||
|
|
||||||
|
hr = WcaInitialize(hInstall, "CreateStartService");
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
hr = WcaGetProperty(L"CustomActionData", &pwzData);
|
||||||
|
ExitOnFailure(hr, "failed to get CustomActionData");
|
||||||
|
|
||||||
|
pwz = pwzData;
|
||||||
|
hr = WcaReadStringFromCaData(&pwz, &svcParams);
|
||||||
|
ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz);
|
||||||
|
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try create start service : %ls", svcParams);
|
||||||
|
|
||||||
|
svcName = svcParams;
|
||||||
|
svcBinary = wcschr(svcParams, L';');
|
||||||
|
if (svcBinary == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to find binary : %ls", svcParams);
|
||||||
|
goto LExit;
|
||||||
|
}
|
||||||
|
svcBinary[0] = L'\0';
|
||||||
|
svcBinary += 1;
|
||||||
|
|
||||||
|
hr = StringCchPrintfW(szSvcDisplayName, cchSvcDisplayName, L"%ls Service", svcName);
|
||||||
|
ExitOnFailure(hr, "Failed to compose a resource identifier string");
|
||||||
|
if (MyCreateServiceW(svcName, szSvcDisplayName, svcBinary)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Service \"%ls\" is created.", svcName);
|
||||||
|
if (MyStartServiceW(svcName)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Service \"%ls\" is started.", svcName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to start service: \"%ls\"", svcName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to create service: \"%ls\"", svcName);
|
||||||
|
}
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
if (pwzData) {
|
||||||
|
ReleaseStr(pwzData);
|
||||||
|
}
|
||||||
|
|
||||||
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(er);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT __stdcall TryStopDeleteService(__in MSIHANDLE hInstall)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD er = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
int nResult = 0;
|
||||||
|
LPWSTR svcName = NULL;
|
||||||
|
LPWSTR pwz = NULL;
|
||||||
|
LPWSTR pwzData = NULL;
|
||||||
|
wchar_t szExeFile[500] = { 0 };
|
||||||
|
DWORD cchExeFile = sizeof(szExeFile) / sizeof(szExeFile[0]);
|
||||||
|
|
||||||
|
hr = WcaInitialize(hInstall, "TryStopDeleteService");
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
hr = WcaGetProperty(L"CustomActionData", &pwzData);
|
||||||
|
ExitOnFailure(hr, "failed to get CustomActionData");
|
||||||
|
|
||||||
|
pwz = pwzData;
|
||||||
|
hr = WcaReadStringFromCaData(&pwz, &svcName);
|
||||||
|
ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try stop and delete service : %ls", svcName);
|
||||||
|
|
||||||
|
if (MyStopServiceW(svcName)) {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
if (IsServiceRunningW(svcName)) {
|
||||||
|
Sleep(100);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Service \"%ls\" is stopped", svcName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to stop service: \"%ls\"", svcName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MyDeleteServiceW(svcName)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Service \"%ls\" is deleted", svcName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to delete service: \"%ls\"", svcName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's really strange that we need sleep here.
|
||||||
|
// But the upgrading may be stucked at "copying new files" because the file is in using.
|
||||||
|
// Steps to reproduce: Install -> stop service in tray --> start service -> upgrade
|
||||||
|
// Sleep(300);
|
||||||
|
|
||||||
|
// Or we can terminate the process
|
||||||
|
hr = StringCchPrintfW(szExeFile, cchExeFile, L"%ls.exe", svcName);
|
||||||
|
ExitOnFailure(hr, "Failed to compose a resource identifier string");
|
||||||
|
TerminateProcessesByNameW(szExeFile, L"--not-in-use");
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
if (pwzData) {
|
||||||
|
ReleaseStr(pwzData);
|
||||||
|
}
|
||||||
|
|
||||||
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(er);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT __stdcall TryDeleteStartupShortcut(__in MSIHANDLE hInstall)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD er = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
wchar_t szShortcut[500] = { 0 };
|
||||||
|
DWORD cchShortcut = sizeof(szShortcut) / sizeof(szShortcut[0]);
|
||||||
|
wchar_t szStartupDir[500] = { 0 };
|
||||||
|
DWORD cchStartupDir = sizeof(szStartupDir) / sizeof(szStartupDir[0]);
|
||||||
|
WCHAR pwszTemp[1024] = L"";
|
||||||
|
|
||||||
|
hr = WcaInitialize(hInstall, "DeleteStartupShortcut");
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"StartupFolder", szStartupDir, &cchStartupDir);
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"ShortcutName", szShortcut, &cchShortcut);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try delete startup shortcut of : \"%ls\"", szShortcut);
|
||||||
|
|
||||||
|
hr = StringCchPrintfW(pwszTemp, 1024, L"%ls%ls.lnk", szStartupDir, szShortcut);
|
||||||
|
ExitOnFailure(hr, "Failed to compose a resource identifier string");
|
||||||
|
|
||||||
|
if (DeleteFile(pwszTemp)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to delete startup shortcut of : \"%ls\"", pwszTemp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Startup shortcut is deleted : \"%ls\"", pwszTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(er);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT __stdcall SetPropertyFromConfig(__in MSIHANDLE hInstall)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD er = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
wchar_t szConfigFile[1024] = { 0 };
|
||||||
|
DWORD cchConfigFile = sizeof(szConfigFile) / sizeof(szConfigFile[0]);
|
||||||
|
wchar_t szConfigKey[500] = { 0 };
|
||||||
|
DWORD cchConfigKey = sizeof(szConfigKey) / sizeof(szConfigKey[0]);
|
||||||
|
wchar_t szPropertyName[500] = { 0 };
|
||||||
|
DWORD cchPropertyName = sizeof(szPropertyName) / sizeof(szPropertyName[0]);
|
||||||
|
std::wstring configValue;
|
||||||
|
|
||||||
|
hr = WcaInitialize(hInstall, "SetPropertyFromConfig");
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"ConfigFile", szConfigFile, &cchConfigFile);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try read config file of : \"%ls\"", szConfigFile);
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"ConfigKey", szConfigKey, &cchConfigKey);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try read configuration, config key : \"%ls\"", szConfigKey);
|
||||||
|
|
||||||
|
MsiGetPropertyW(hInstall, L"PropertyName", szPropertyName, &cchPropertyName);
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Try read configuration, property name : \"%ls\"", szPropertyName);
|
||||||
|
|
||||||
|
configValue = ReadConfig(szConfigFile, szConfigKey);
|
||||||
|
MsiSetPropertyW(hInstall, szPropertyName, configValue.c_str());
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(er);
|
||||||
|
}
|
||||||
|
@ -5,3 +5,8 @@ EXPORTS
|
|||||||
RemoveInstallFolder
|
RemoveInstallFolder
|
||||||
TerminateProcesses
|
TerminateProcesses
|
||||||
AddFirewallRules
|
AddFirewallRules
|
||||||
|
SetPropertyIsServiceRunning
|
||||||
|
TryStopDeleteService
|
||||||
|
CreateStartService
|
||||||
|
TryDeleteStartupShortcut
|
||||||
|
SetPropertyFromConfig
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Common.h" />
|
||||||
<ClInclude Include="framework.h" />
|
<ClInclude Include="framework.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -64,6 +65,8 @@
|
|||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ReadConfig.cpp" />
|
||||||
|
<ClCompile Include="ServiceUtils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="CustomActions.def" />
|
<None Include="CustomActions.def" />
|
||||||
|
36
res/msi/CustomActions/ReadConfig.cpp
Normal file
36
res/msi/CustomActions/ReadConfig.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <cwctype>
|
||||||
|
|
||||||
|
void trim(std::wstring& str) {
|
||||||
|
str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](wchar_t ch) {
|
||||||
|
return !std::iswspace(ch);
|
||||||
|
}));
|
||||||
|
str.erase(std::find_if(str.rbegin(), str.rend(), [](wchar_t ch) {
|
||||||
|
return !std::iswspace(ch);
|
||||||
|
}).base(), str.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring ReadConfig(const std::wstring& filename, const std::wstring& key)
|
||||||
|
{
|
||||||
|
std::wstring configValue;
|
||||||
|
std::wstring line;
|
||||||
|
std::wifstream file(filename);
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
trim(line);
|
||||||
|
if (line.find(key) == 0) {
|
||||||
|
std::size_t position = line.find(L"=", key.size());
|
||||||
|
if (position != std::string::npos) {
|
||||||
|
configValue = line.substr(position + 1);
|
||||||
|
trim(configValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
return configValue;
|
||||||
|
}
|
173
res/msi/CustomActions/ServiceUtils.cpp
Normal file
173
res/msi/CustomActions/ServiceUtils.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// https://learn.microsoft.com/en-us/windows/win32/services/installing-a-service
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
bool MyCreateServiceW(LPCWSTR serviceName, LPCWSTR displayName, LPCWSTR binaryPath)
|
||||||
|
{
|
||||||
|
SC_HANDLE schSCManager;
|
||||||
|
SC_HANDLE schService;
|
||||||
|
|
||||||
|
// Get a handle to the SCM database.
|
||||||
|
schSCManager = OpenSCManager(
|
||||||
|
NULL, // local computer
|
||||||
|
NULL, // ServicesActive database
|
||||||
|
SC_MANAGER_ALL_ACCESS); // full access rights
|
||||||
|
|
||||||
|
if (NULL == schSCManager)
|
||||||
|
{
|
||||||
|
WcaLog(LOGMSG_STANDARD, "OpenSCManager failed (%d)\n", GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the service
|
||||||
|
schService = CreateService(
|
||||||
|
schSCManager, // SCM database
|
||||||
|
serviceName, // name of service
|
||||||
|
displayName, // service name to display
|
||||||
|
SERVICE_ALL_ACCESS, // desired access
|
||||||
|
SERVICE_WIN32_OWN_PROCESS, // service type
|
||||||
|
SERVICE_AUTO_START, // start type
|
||||||
|
SERVICE_ERROR_NORMAL, // error control type
|
||||||
|
binaryPath, // path to service's binary
|
||||||
|
NULL, // no load ordering group
|
||||||
|
NULL, // no tag identifier
|
||||||
|
NULL, // no dependencies
|
||||||
|
NULL, // LocalSystem account
|
||||||
|
NULL); // no password
|
||||||
|
if (schService == NULL)
|
||||||
|
{
|
||||||
|
WcaLog(LOGMSG_STANDARD, "CreateService failed (%d)\n", GetLastError());
|
||||||
|
CloseServiceHandle(schSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Service installed successfully\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseServiceHandle(schService);
|
||||||
|
CloseServiceHandle(schSCManager);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyDeleteServiceW(LPCWSTR serviceName)
|
||||||
|
{
|
||||||
|
SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
if (hSCManager == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open Service Control Manager");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_HANDLE hService = OpenServiceW(hSCManager, serviceName, SERVICE_STOP | DELETE);
|
||||||
|
if (hService == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open service: %ls", serviceName);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVICE_STATUS serviceStatus;
|
||||||
|
if (ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Stopping service: %ls", serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = DeleteService(hService);
|
||||||
|
if (!success) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to delete service: %ls", serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseServiceHandle(hService);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyStartServiceW(LPCWSTR serviceName)
|
||||||
|
{
|
||||||
|
SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
if (hSCManager == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open Service Control Manager");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_HANDLE hService = OpenServiceW(hSCManager, serviceName, SERVICE_START);
|
||||||
|
if (hService == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open service: %ls", serviceName);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = StartService(hService, 0, NULL);
|
||||||
|
if (!success) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to start service: %ls", serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseServiceHandle(hService);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyStopServiceW(LPCWSTR serviceName)
|
||||||
|
{
|
||||||
|
SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
if (hSCManager == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open Service Control Manager");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_HANDLE hService = OpenServiceW(hSCManager, serviceName, SERVICE_STOP);
|
||||||
|
if (hService == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open service: %ls", serviceName);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVICE_STATUS serviceStatus;
|
||||||
|
if (!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to stop service: %ls", serviceName);
|
||||||
|
CloseServiceHandle(hService);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseServiceHandle(hService);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsServiceRunningW(LPCWSTR serviceName)
|
||||||
|
{
|
||||||
|
SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
if (hSCManager == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open Service Control Manager");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_HANDLE hService = OpenServiceW(hSCManager, serviceName, SERVICE_QUERY_STATUS);
|
||||||
|
if (hService == NULL) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to open service: %ls", serviceName);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVICE_STATUS_PROCESS serviceStatus;
|
||||||
|
DWORD bytesNeeded;
|
||||||
|
if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, reinterpret_cast<LPBYTE>(&serviceStatus), sizeof(serviceStatus), &bytesNeeded)) {
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Failed to query service: %ls", serviceName);
|
||||||
|
CloseServiceHandle(hService);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRunning = (serviceStatus.dwCurrentState == SERVICE_RUNNING);
|
||||||
|
|
||||||
|
CloseServiceHandle(hService);
|
||||||
|
CloseServiceHandle(hSCManager);
|
||||||
|
|
||||||
|
return isRunning;
|
||||||
|
}
|
@ -9,35 +9,67 @@
|
|||||||
<File Id="$(var.Product).exe" Name="$(var.Product).exe" KeyPath="yes" Checksum="yes">
|
<File Id="$(var.Product).exe" Name="$(var.Product).exe" KeyPath="yes" Checksum="yes">
|
||||||
<!--<fire:FirewallException Id="RustDeskEx" Name="$(var.Product) Service" Scope="any" IgnoreFailure="yes" />-->
|
<!--<fire:FirewallException Id="RustDeskEx" Name="$(var.Product) Service" Scope="any" IgnoreFailure="yes" />-->
|
||||||
</File>
|
</File>
|
||||||
<ServiceInstall Id="ServiceInstaller" Type="ownProcess" Vital="yes" Name="$(var.Product)" DisplayName="!(loc.Service_DisplayName)" Description="!(loc.Service_Description)" Start="auto" Account="LocalSystem" ErrorControl="ignore" Interactive="no" Arguments="--service" />
|
|
||||||
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="$(var.Product)" Wait="yes" />
|
|
||||||
</Component>
|
</Component>
|
||||||
</DirectoryRef>
|
</DirectoryRef>
|
||||||
|
|
||||||
<SetProperty Id="RestartService" Value=""net" start $(var.Product)" Before="RestartService" Sequence="execute" />
|
|
||||||
<CustomAction Id="RestartService" DllEntry="WixQuietExec" Execute="deferred" Return="asyncWait" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
|
|
||||||
|
|
||||||
<CustomAction Id="RemoveInstallFolder.SetParam" Return="check" Property="RemoveInstallFolder" Value="[INSTALLFOLDER]" />
|
<CustomAction Id="RemoveInstallFolder.SetParam" Return="check" Property="RemoveInstallFolder" Value="[INSTALLFOLDER]" />
|
||||||
<CustomAction Id="AddFirewallRules.SetParam" Return="check" Property="AddFirewallRules" Value="1[INSTALLFOLDER]$(var.Product).exe" />
|
<CustomAction Id="AddFirewallRules.SetParam" Return="check" Property="AddFirewallRules" Value="1[INSTALLFOLDER]$(var.Product).exe" />
|
||||||
<CustomAction Id="RemoveFirewallRules.SetParam" Return="check" Property="RemoveFirewallRules" Value="0[INSTALLFOLDER]$(var.Product).exe" />
|
<CustomAction Id="RemoveFirewallRules.SetParam" Return="check" Property="RemoveFirewallRules" Value="0[INSTALLFOLDER]$(var.Product).exe" />
|
||||||
|
<CustomAction Id="CreateStartService.SetParam" Return="check" Property="CreateStartService" Value="$(var.Product);"[INSTALLFOLDER]$(var.Product).exe" --service" />
|
||||||
|
<CustomAction Id="TryStopDeleteService.SetParam" Return="check" Property="TryStopDeleteService" Value="$(var.Product)" />
|
||||||
|
|
||||||
|
<CustomAction Id="LaunchApp" ExeCommand="" Return="asyncNoWait" FileRef="RustDesk.exe" />
|
||||||
|
<CustomAction Id="LaunchAppTray" ExeCommand=" --tray" Return="asyncNoWait" FileRef="RustDesk.exe" />
|
||||||
|
<Property Id="TerminateProcesses" Value="RustDeskTest.exe" />
|
||||||
|
<CustomAction Id="TerminateProcesses.SetParam" Return="check" Property="TerminateProcesses" Value="$(var.Product).exe" />
|
||||||
|
<CustomAction Id="TerminateBrokers.SetParam" Return="check" Property="TerminateProcesses" Value="RuntimeBroker_rustdesk.exe" />
|
||||||
|
<CustomAction Id="SetPropertyIsServiceRunning.SetParam.AppName" Return="check" Property="AppName" Value="$(var.Product)" />
|
||||||
|
<CustomAction Id="SetPropertyIsServiceRunning.SetParam.PropertyName" Return="check" Property="PropertyName" Value="STOP_SERVICE" />
|
||||||
|
<CustomAction Id="SetPropertyServiceStop.SetParam.ConfigFile" Return="check" Property="ConfigFile" Value="[AppDataFolder]rustdesk\config\rustdesk2.toml" />
|
||||||
|
<CustomAction Id="SetPropertyServiceStop.SetParam.ConfigKey" Return="check" Property="ConfigKey" Value="stop-service" />
|
||||||
|
<CustomAction Id="SetPropertyServiceStop.SetParam.PropertyName" Return="check" Property="PropertyName" Value="STOP_SERVICE" />
|
||||||
|
<CustomAction Id="TryDeleteStartupShortcut.SetParam" Return="check" Property="ShortcutName" Value="$(var.Product) Tray" />
|
||||||
<InstallExecuteSequence>
|
<InstallExecuteSequence>
|
||||||
|
|
||||||
<!--The ServiceControl element above handles starting/stopping the server on install/uninstall,
|
<Custom Action="SetPropertyIsServiceRunning" After="InstallInitialize" Condition="Installed" />
|
||||||
however it also needs to be restarted after a modify or repair install. This action does
|
<Custom Action="SetPropertyIsServiceRunning.SetParam.AppName" Before="SetPropertyIsServiceRunning" Condition="Installed" />
|
||||||
that provided the server feature is already installed and not being uninstalled.-->
|
<Custom Action="SetPropertyIsServiceRunning.SetParam.PropertyName" Before="SetPropertyIsServiceRunning" Condition="Installed" />
|
||||||
|
|
||||||
|
<Custom Action="SetPropertyServiceStop" After="InstallInitialize" Condition="NOT Installed" />
|
||||||
|
<Custom Action="SetPropertyServiceStop.SetParam.ConfigFile" Before="SetPropertyServiceStop" Condition="NOT Installed" />
|
||||||
|
<Custom Action="SetPropertyServiceStop.SetParam.ConfigKey" Before="SetPropertyServiceStop" Condition="NOT Installed" />
|
||||||
|
<Custom Action="SetPropertyServiceStop.SetParam.PropertyName" Before="SetPropertyServiceStop" Condition="NOT Installed" />
|
||||||
|
|
||||||
|
<Custom Action="CreateStartService" Before="InstallFinalize" Condition="NOT STOP_SERVICE="'Y'"" />
|
||||||
|
<Custom Action="CreateStartService.SetParam" Before="CreateStartService" Condition="NOT STOP_SERVICE="'Y'"" />
|
||||||
|
|
||||||
<Custom Action="RestartService" Before="InstallFinalize" />
|
|
||||||
<Custom Action="CustomActionHello" Before="InstallFinalize" />
|
<Custom Action="CustomActionHello" Before="InstallFinalize" />
|
||||||
|
|
||||||
|
<!--Shortcut is in InstallValidate section. So we just let it be created, then try delete if stopping service.-->
|
||||||
|
<Custom Action="TryDeleteStartupShortcut" After="InstallFinalize" Condition="STOP_SERVICE="'Y'"" />
|
||||||
|
<Custom Action="TryDeleteStartupShortcut.SetParam" Before="SetPropertyIsServiceRunning" Condition="STOP_SERVICE="'Y'"" />
|
||||||
|
|
||||||
|
<!-- Launch ClientLauncher if installing or already installed and not uninstalling -->
|
||||||
|
<Custom Action="LaunchApp" After="InstallFinalize" />
|
||||||
|
<Custom Action="LaunchAppTray" After="InstallFinalize" Condition="NOT STOP_SERVICE="'Y'""/>
|
||||||
|
|
||||||
<!--Workaround of "fire:FirewallException". If Outbound="Yes" or Outbound="true", the following error occurs.-->
|
<!--Workaround of "fire:FirewallException". If Outbound="Yes" or Outbound="true", the following error occurs.-->
|
||||||
<!--ExecFirewallExceptions: Error 0x80070057: failed to add app to the authorized apps list-->
|
<!--ExecFirewallExceptions: Error 0x80070057: failed to add app to the authorized apps list-->
|
||||||
<Custom Action="AddFirewallRules.SetParam" Before="InstallFinalize" Condition="NOT Installed"/>
|
<Custom Action="AddFirewallRules" Before="InstallFinalize"/>
|
||||||
<Custom Action="AddFirewallRules" After="AddFirewallRules.SetParam"/>
|
<Custom Action="AddFirewallRules.SetParam" Before="AddFirewallRules" Condition="NOT Installed"/>
|
||||||
|
|
||||||
<Custom Action="RemoveInstallFolder.SetParam" After="RemoveFiles" Condition="Installed AND UPGRADINGPRODUCTCODE" />
|
<Custom Action="RemoveInstallFolder" Before="RemoveFiles" Condition="Installed AND NOT UPGRADINGPRODUCTCODE AND REMOVE"/>
|
||||||
<Custom Action="RemoveInstallFolder" After="RemoveInstallFolder.SetParam"/>
|
<Custom Action="RemoveInstallFolder.SetParam" Before="RemoveInstallFolder" Condition="Installed AND NOT UPGRADINGPRODUCTCODE AND REMOVE"/>
|
||||||
<Custom Action="RemoveFirewallRules.SetParam" Before="RemoveFiles"/>
|
<Custom Action="TryStopDeleteService" Before="RemoveInstallFolder.SetParam" />
|
||||||
<Custom Action="RemoveFirewallRules" After="RemoveFirewallRules.SetParam"/>
|
<Custom Action="TryStopDeleteService.SetParam" Before="TryStopDeleteService" />
|
||||||
|
|
||||||
|
<Custom Action="RemoveFirewallRules" Before="RemoveFiles"/>
|
||||||
|
<Custom Action="RemoveFirewallRules.SetParam" Before="RemoveFirewallRules"/>
|
||||||
|
|
||||||
|
<Custom Action="TerminateProcesses" Before="RemoveFiles"/>
|
||||||
|
<Custom Action="TerminateProcesses.SetParam" Before="TerminateProcesses"/>
|
||||||
|
<Custom Action="TerminateBrokers" Before="RemoveFiles"/>
|
||||||
|
<Custom Action="TerminateBrokers.SetParam" Before="TerminateBrokers"/>
|
||||||
</InstallExecuteSequence>
|
</InstallExecuteSequence>
|
||||||
|
|
||||||
<!-- Shortcuts -->
|
<!-- Shortcuts -->
|
||||||
@ -58,11 +90,6 @@
|
|||||||
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.StartMenu.Shortcut" Type="string" Value="1" KeyPath="yes" />
|
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.StartMenu.Shortcut" Type="string" Value="1" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<Component Id="App.StartMenu.ShortcutTray" Guid="9362C316-40BB-41C1-859C-08182AA47E8D" Condition="STARTMENUSHORTCUTS = 1">
|
|
||||||
<Shortcut Id="App.StartMenu.ShortcutTray" Name="!(loc.SC_Client_Tray)" Description="!(loc.SC_Client_Tray_Desc)" Target="[!RustDesk.exe]" Arguments="--tray" Icon="AppIcon" WorkingDirectory="INSTALLFOLDER" />
|
|
||||||
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.StartMenu.ShortcutTray" Type="string" Value="1" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
|
|
||||||
<Component Id="App.StartMenu.ShortcutUninstall" Guid="E100D7F8-D607-4513-28DA-2C95E5EA698E" Condition="STARTMENUSHORTCUTS = 1">
|
<Component Id="App.StartMenu.ShortcutUninstall" Guid="E100D7F8-D607-4513-28DA-2C95E5EA698E" Condition="STARTMENUSHORTCUTS = 1">
|
||||||
<Shortcut Id="App.StartMenu.ShortcutUninstall" Name="!(loc.SC_Uninstall)" Description="!(loc.SC_Uninstall_Desc)" Target="[System6432Folder]msiexec.exe" Arguments="/x [ProductCode]" Icon="AppIcon" />
|
<Shortcut Id="App.StartMenu.ShortcutUninstall" Name="!(loc.SC_Uninstall)" Description="!(loc.SC_Uninstall_Desc)" Target="[System6432Folder]msiexec.exe" Arguments="/x [ProductCode]" Icon="AppIcon" />
|
||||||
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.StartMenu.ShortcutUninstall" Type="string" Value="1" KeyPath="yes" />
|
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.StartMenu.ShortcutUninstall" Type="string" Value="1" KeyPath="yes" />
|
||||||
@ -74,6 +101,12 @@
|
|||||||
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.Desktop.Shortcut" Type="string" Value="1" KeyPath="yes" />
|
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.Desktop.Shortcut" Type="string" Value="1" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
</StandardDirectory>
|
</StandardDirectory>
|
||||||
|
<StandardDirectory Id="StartupFolder">
|
||||||
|
<Component Id="App.StartupFolder.ShortcutTray" Guid="B1D1E2BB-E53E-E159-DB7C-744D5C726A8C" Condition="STARTUPSHORTCUTS = 1">
|
||||||
|
<Shortcut Id="App.StartupFolder.ShortcutTray" Name="!(loc.SC_Client_Tray)" Description="!(loc.SC_Client_Tray_Desc)" Target="[!RustDesk.exe]" Arguments="--tray" Icon="AppIcon" WorkingDirectory="INSTALLFOLDER" />
|
||||||
|
<RegistryValue Root="HKCU" Key="Software\$(var.Product)" Name="App.StartupFolder.ShortcutTray" Type="string" Value="1" KeyPath="yes" />
|
||||||
|
</Component>
|
||||||
|
</StandardDirectory>
|
||||||
|
|
||||||
<!--<DirectoryRef Id="INSTALLFOLDER">
|
<!--<DirectoryRef Id="INSTALLFOLDER">
|
||||||
<Component Id="App.UninstallShortcut" Guid="FB0F2AC7-2AE5-4C54-B860-5E472620B6B1">
|
<Component Id="App.UninstallShortcut" Guid="FB0F2AC7-2AE5-4C54-B860-5E472620B6B1">
|
||||||
@ -86,8 +119,8 @@
|
|||||||
<ComponentRef Id="App.Desktop.Shortcut" />
|
<ComponentRef Id="App.Desktop.Shortcut" />
|
||||||
<!--<ComponentRef Id="App.UninstallShortcut" />-->
|
<!--<ComponentRef Id="App.UninstallShortcut" />-->
|
||||||
<ComponentRef Id="App.StartMenu.Shortcut" />
|
<ComponentRef Id="App.StartMenu.Shortcut" />
|
||||||
<ComponentRef Id="App.StartMenu.ShortcutTray" />
|
|
||||||
<ComponentRef Id="App.StartMenu.ShortcutUninstall" />
|
<ComponentRef Id="App.StartMenu.ShortcutUninstall" />
|
||||||
|
<ComponentRef Id="App.StartupFolder.ShortcutTray" />
|
||||||
|
|
||||||
<!--$AutoComonentStart$-->
|
<!--$AutoComonentStart$-->
|
||||||
<!--$AutoComponentEnd$-->
|
<!--$AutoComponentEnd$-->
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
<Property Id="AddRemovePropertiesFile" Value="1" />
|
<Property Id="AddRemovePropertiesFile" Value="1" />
|
||||||
|
|
||||||
|
<!--STOP_SERVICE is set to 'Y'. Because the cofig value may be empty or 'Y'-->
|
||||||
|
<Property Id="STOP_SERVICE" Value="'Y'" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Support entries shown when clicking "Click here for support information"
|
Support entries shown when clicking "Click here for support information"
|
||||||
in Control Panel's Add/Remove Programs https://learn.microsoft.com/en-us/windows/win32/msi/property-reference
|
in Control Panel's Add/Remove Programs https://learn.microsoft.com/en-us/windows/win32/msi/property-reference
|
||||||
|
@ -7,8 +7,13 @@
|
|||||||
<CustomAction Id="CustomActionHello" DllEntry="CustomActionHello" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
<CustomAction Id="CustomActionHello" DllEntry="CustomActionHello" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
<CustomAction Id="RemoveInstallFolder" DllEntry="RemoveInstallFolder" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
<CustomAction Id="RemoveInstallFolder" DllEntry="RemoveInstallFolder" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
<CustomAction Id="TerminateProcesses" DllEntry="TerminateProcesses" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
<CustomAction Id="TerminateProcesses" DllEntry="TerminateProcesses" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
|
<CustomAction Id="TerminateBrokers" DllEntry="TerminateProcesses" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
<CustomAction Id="AddFirewallRules" DllEntry="AddFirewallRules" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
<CustomAction Id="AddFirewallRules" DllEntry="AddFirewallRules" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
<CustomAction Id="RemoveFirewallRules" DllEntry="AddFirewallRules" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
<CustomAction Id="RemoveFirewallRules" DllEntry="AddFirewallRules" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
|
<CustomAction Id="SetPropertyIsServiceRunning" DllEntry="SetPropertyIsServiceRunning" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
|
<CustomAction Id="CreateStartService" DllEntry="CreateStartService" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
|
<CustomAction Id="TryStopDeleteService" DllEntry="TryStopDeleteService" Impersonate="no" Execute="deferred" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
|
<CustomAction Id="TryDeleteStartupShortcut" DllEntry="TryDeleteStartupShortcut" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
|
<CustomAction Id="SetPropertyServiceStop" DllEntry="SetPropertyFromConfig" Impersonate="yes" Execute="immediate" Return="ignore" BinaryRef="Custom_Actions_Dll"/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</Wix>
|
</Wix>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
below should be set, then they will update these properties with their values only if set. -->
|
below should be set, then they will update these properties with their values only if set. -->
|
||||||
<Property Id="STARTMENUSHORTCUTS" Value="1" Secure="yes"></Property>
|
<Property Id="STARTMENUSHORTCUTS" Value="1" Secure="yes"></Property>
|
||||||
<Property Id="DESKTOPSHORTCUTS" Value="1" Secure="yes"></Property>
|
<Property Id="DESKTOPSHORTCUTS" Value="1" Secure="yes"></Property>
|
||||||
|
<Property Id="STARTUPSHORTCUTS" Value="1" Secure="yes"></Property>
|
||||||
|
|
||||||
<!-- These properties get set from either the command line, bundle or registry value,
|
<!-- These properties get set from either the command line, bundle or registry value,
|
||||||
if set they update the properties above with their value. -->
|
if set they update the properties above with their value. -->
|
||||||
|
@ -26,24 +26,14 @@
|
|||||||
</InstallUISequence>
|
</InstallUISequence>
|
||||||
|
|
||||||
<InstallExecuteSequence>
|
<InstallExecuteSequence>
|
||||||
<!-- Launch ClientLauncher if installing or already installed and not uninstalling -->
|
|
||||||
<Custom Action="LaunchApp" After="InstallFinalize" />
|
|
||||||
<Custom Action="LaunchAppTray" After="InstallFinalize" />
|
|
||||||
|
|
||||||
<InstallExecute After="RemoveExistingProducts" />
|
<InstallExecute After="RemoveExistingProducts" />
|
||||||
|
|
||||||
<!--Only do InstallValidate if is not Uninstall-->
|
<!--Only do InstallValidate if is not Uninstall-->
|
||||||
<!--Do InstallValidate if is Install, Change, Repair, Upgrade-->
|
<!--<InstallValidate Condition="NOT (Installed AND REMOVE AND NOT UPGRADINGPRODUCTCODE )" />-->
|
||||||
<InstallValidate Condition="NOT (Installed AND REMOVE AND NOT UPGRADINGPRODUCTCODE )" />
|
<!--Only do InstallValidate if is Install-->
|
||||||
|
<InstallValidate Condition="NOT Installed" />
|
||||||
<Custom Action="TerminateProcesses" Before="RemoveFiles"/>
|
|
||||||
<Custom Action="TerminateProcesses.SetParam" Before="TerminateProcesses"/>
|
|
||||||
|
|
||||||
</InstallExecuteSequence>
|
</InstallExecuteSequence>
|
||||||
<CustomAction Id="LaunchApp" ExeCommand="" Return="asyncNoWait" FileRef="RustDesk.exe" />
|
|
||||||
<CustomAction Id="LaunchAppTray" ExeCommand=" --tray" Return="asyncNoWait" FileRef="RustDesk.exe" />
|
|
||||||
<Property Id="TerminateProcesses" Value="RustDeskTest.exe" />
|
|
||||||
<CustomAction Id="TerminateProcesses.SetParam" Return="check" Property="TerminateProcesses" Value="$(var.Product).exe" />
|
|
||||||
|
|
||||||
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" Schedule="afterInstallInitialize" AllowSameVersionUpgrades="yes" />
|
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" Schedule="afterInstallInitialize" AllowSameVersionUpgrades="yes" />
|
||||||
|
|
||||||
|
@ -39,5 +39,6 @@ Run `msiexec /i package.msi /l*v install.log` to record the log.
|
|||||||
|
|
||||||
## Refs
|
## Refs
|
||||||
|
|
||||||
|
1. [windows-installer-portal](https://learn.microsoft.com/en-us/windows/win32/Msi/windows-installer-portal)
|
||||||
1. [wxs](https://wixtoolset.org/docs/schema/wxs/)
|
1. [wxs](https://wixtoolset.org/docs/schema/wxs/)
|
||||||
1. [wxs github](https://github.com/wixtoolset/wix)
|
1. [wxs github](https://github.com/wixtoolset/wix)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user