Merge pull request #5696 from duplicati/feature/fix-silent-upgrade-error

Fix MSI /quiet upgrade error
This commit is contained in:
Kenneth Skovhede
2024-11-24 09:16:29 +01:00
committed by GitHub
8 changed files with 293 additions and 4 deletions
@@ -69,7 +69,11 @@
<!-- Remove old versions -->
<InstallExecuteSequence>
<!-- Note: This is suboptimal, but the ref counting is not working, so we use Early REP -->
<RemoveExistingProducts Before="CostInitialize" />
<RemoveExistingProducts After="FindRelatedProducts" />
<!-- Stop the service before install -->
<Custom Action="StopService" Before="RemoveExistingProducts"></Custom>
<Custom Action="StartService" After="InstallFiles">SERVICE_WAS_STOPPED=1</Custom>
</InstallExecuteSequence>
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
@@ -79,5 +83,20 @@
<Icon Id="DuplicatiIcon.exe" SourceFile="$(var.HarvestPath)Duplicati.Agent.exe" />
<!-- Service restart code below -->
<Binary Id="StopServiceScript" SourceFile="StopService.js" />
<Binary Id="StartServiceScript" SourceFile="StartService.js" />
<CustomAction Id="StopService"
BinaryKey="StopServiceScript"
JScriptCall="CustomAction"
Execute="immediate"
Property="SERVICE_WAS_STOPPED" />
<CustomAction Id="StartService"
BinaryKey="StartServiceScript"
JScriptCall="CustomAction"
Execute="deferred"
Return="check" />
</Product>
</Wix>
@@ -0,0 +1,47 @@
function LogMessage(message) {
var record = Session.Installer.CreateRecord(1);
record.StringData(1) = message;
var INSTALLMESSAGE_INFO = 0x04000000;
// MessageType 1 = Shown as warning in the UI
Session.Message(INSTALLMESSAGE_INFO, record); // MessageType 1 = informational log
}
// Function to start a service
function StartService(serviceName) {
var service;
try {
// Connect to the WMI service
var locator = new ActiveXObject("WbemScripting.SWbemLocator");
var root = locator.ConnectServer(".", "root\\CIMV2");
// Query the service
var query = "SELECT * FROM Win32_Service WHERE Name = '" + serviceName + "'";
var services = root.ExecQuery(query);
// Check if the service exists and start it if not already running
var enumerator = new Enumerator(services);
if (!enumerator.atEnd()) {
service = enumerator.item();
if (service.State != "Running") {
service.StartService();
LogMessage("Service '" + serviceName + "' started successfully.");
return 0; // Success
} else {
LogMessage("Service '" + serviceName + "' is already running.");
return 0; // Success
}
} else {
LogMessage("Service '" + serviceName + "' not found.");
return 1; // Failure
}
} catch (e) {
LogMessage("Error starting service '" + serviceName + "': " + e.message);
return 1; // Failure
}
}
// Entry point for the custom action
function CustomAction() {
return StartService("Duplicati.Agent");
}
@@ -0,0 +1,78 @@
function LogMessage(message) {
var record = Session.Installer.CreateRecord(1);
record.StringData(1) = message;
var INSTALLMESSAGE_INFO = 0x04000000;
// MessageType 1 = Shown as warning in the UI
Session.Message(INSTALLMESSAGE_INFO, record);
}
// Function to check the status of a Windows service
function CheckServiceStatus(serviceName) {
var locator;
var root;
var query;
var services;
var enumerator;
var service;
try {
// Connect to WMI (Windows Management Instrumentation)
locator = new ActiveXObject("WbemScripting.SWbemLocator");
root = locator.ConnectServer(".", "root\\CIMV2");
// Query for the service by name
query = "SELECT * FROM Win32_Service WHERE Name = '" + serviceName + "'";
services = root.ExecQuery(query);
// Enumerate the results
enumerator = new Enumerator(services);
if (!enumerator.atEnd()) {
service = enumerator.item();
// Check if the service is running
if (service.State == "Running") {
LogMessage("Service '" + serviceName + "' is running. Attempting to stop it.");
// Attempt to stop the service
var result = service.StopService();
if (result === 0) {
LogMessage("Service '" + serviceName + "' stopped successfully.");
} else {
LogMessage("Failed to stop service '" + serviceName + "'. Error code: " + result);
}
// Service was running and stopped
Session.Property("SERVICE_WAS_STOPPED") = "1";
return true;
} else {
LogMessage("Service '" + serviceName + "' is not running.");
return false; // Service is not running
}
} else {
LogMessage("Service '" + serviceName + "' not found.");
return null; // Service not found
}
} catch (e) {
LogMessage("Error checking service status: " + e.message);
return null; // Error occurred
}
}
// Entry point for the custom action
function CustomAction() {
// Check the service status
var isRunning = CheckServiceStatus("Duplicati.Agent");
// Set a property in the installer to track the service status
if (isRunning === true) {
Session.Property("SERVICE_WAS_STOPPED") = "1"; // Service was running
} else if (isRunning === false) {
Session.Property("SERVICE_WAS_STOPPED") = "0"; // Service was not running
} else {
// Service not found or error occurred
LogMessage("Failed to determine service status.");
Session.Property("SERVICE_WAS_STOPPED") = "0"; // Service was not running
}
return 0; // Success
}
@@ -1,6 +1,6 @@
<Include>
<!-- Never change the UpgradeCode -->
<?define UpgradeCode="bc5a1c94-2bf2-4273-9d8f-780d162cb30e" ?>
<?define UpgradeCode="BC5A1C94-2BF2-4273-9D8F-780D162CB30E" ?>
<!-- Remember to change product version on each install -->
<?define ProductVersion="2.0.8.104" ?>
@@ -70,7 +70,11 @@
<!-- Remove old versions -->
<InstallExecuteSequence>
<!-- Note: This is suboptimal, but the ref counting is not working, so we use Early REP -->
<RemoveExistingProducts Before="CostInitialize" />
<RemoveExistingProducts After="FindRelatedProducts" />
<!-- Stop the service before install -->
<Custom Action="StopService" Before="RemoveExistingProducts"></Custom>
<Custom Action="StartService" After="InstallFiles">SERVICE_WAS_STOPPED=1</Custom>
</InstallExecuteSequence>
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
@@ -79,6 +83,22 @@
</Upgrade>
<Icon Id="DuplicatiIcon.exe" SourceFile="$(var.HarvestPath)Duplicati.GUI.TrayIcon.exe" />
<!-- Service restart code below -->
<Binary Id="StopServiceScript" SourceFile="StopService.js" />
<Binary Id="StartServiceScript" SourceFile="StartService.js" />
<CustomAction Id="StopService"
BinaryKey="StopServiceScript"
JScriptCall="CustomAction"
Execute="immediate"
Property="SERVICE_WAS_STOPPED" />
<CustomAction Id="StartService"
BinaryKey="StartServiceScript"
JScriptCall="CustomAction"
Execute="deferred"
Return="check" />
</Product>
</Wix>
@@ -0,0 +1,47 @@
function LogMessage(message) {
var record = Session.Installer.CreateRecord(1);
record.StringData(1) = message;
var INSTALLMESSAGE_INFO = 0x04000000;
// MessageType 1 = Shown as warning in the UI
Session.Message(INSTALLMESSAGE_INFO, record); // MessageType 1 = informational log
}
// Function to start a service
function StartService(serviceName) {
var service;
try {
// Connect to the WMI service
var locator = new ActiveXObject("WbemScripting.SWbemLocator");
var root = locator.ConnectServer(".", "root\\CIMV2");
// Query the service
var query = "SELECT * FROM Win32_Service WHERE Name = '" + serviceName + "'";
var services = root.ExecQuery(query);
// Check if the service exists and start it if not already running
var enumerator = new Enumerator(services);
if (!enumerator.atEnd()) {
service = enumerator.item();
if (service.State != "Running") {
service.StartService();
LogMessage("Service '" + serviceName + "' started successfully.");
return 0; // Success
} else {
LogMessage("Service '" + serviceName + "' is already running.");
return 0; // Success
}
} else {
LogMessage("Service '" + serviceName + "' not found.");
return 1; // Failure
}
} catch (e) {
LogMessage("Error starting service '" + serviceName + "': " + e.message);
return 1; // Failure
}
}
// Entry point for the custom action
function CustomAction() {
return StartService("Duplicati");
}
@@ -0,0 +1,78 @@
function LogMessage(message) {
var record = Session.Installer.CreateRecord(1);
record.StringData(1) = message;
var INSTALLMESSAGE_INFO = 0x04000000;
// MessageType 1 = Shown as warning in the UI
Session.Message(INSTALLMESSAGE_INFO, record);
}
// Function to check the status of a Windows service
function CheckServiceStatus(serviceName) {
var locator;
var root;
var query;
var services;
var enumerator;
var service;
try {
// Connect to WMI (Windows Management Instrumentation)
locator = new ActiveXObject("WbemScripting.SWbemLocator");
root = locator.ConnectServer(".", "root\\CIMV2");
// Query for the service by name
query = "SELECT * FROM Win32_Service WHERE Name = '" + serviceName + "'";
services = root.ExecQuery(query);
// Enumerate the results
enumerator = new Enumerator(services);
if (!enumerator.atEnd()) {
service = enumerator.item();
// Check if the service is running
if (service.State == "Running") {
LogMessage("Service '" + serviceName + "' is running. Attempting to stop it.");
// Attempt to stop the service
var result = service.StopService();
if (result === 0) {
LogMessage("Service '" + serviceName + "' stopped successfully.");
} else {
LogMessage("Failed to stop service '" + serviceName + "'. Error code: " + result);
}
// Service was running and stopped
Session.Property("SERVICE_WAS_STOPPED") = "1";
return true;
} else {
LogMessage("Service '" + serviceName + "' is not running.");
return false; // Service is not running
}
} else {
LogMessage("Service '" + serviceName + "' not found.");
return null; // Service not found
}
} catch (e) {
LogMessage("Error checking service status: " + e.message);
return null; // Error occurred
}
}
// Entry point for the custom action
function CustomAction() {
// Check the service status
var isRunning = CheckServiceStatus("Duplicati");
// Set a property in the installer to track the service status
if (isRunning === true) {
Session.Property("SERVICE_WAS_STOPPED") = "1"; // Service was running
} else if (isRunning === false) {
Session.Property("SERVICE_WAS_STOPPED") = "0"; // Service was not running
} else {
// Service not found or error occurred
LogMessage("Failed to determine service status.");
Session.Property("SERVICE_WAS_STOPPED") = "0"; // Service was not running
}
return 0; // Success
}
@@ -1,6 +1,6 @@
<Include>
<!-- Never change the UpgradeCode -->
<?define UpgradeCode="1c94bc5a-2bf2-4273-9d8f-2cb30e780d16" ?>
<?define UpgradeCode="1C94BC5A-2BF2-4273-9D8F-2CB30E780D16" ?>
<!-- Remember to change product version on each install -->
<?define ProductVersion="2.0.8.104" ?>