fix uninstall apps for msiexec and change software api again #7859

Signed-off-by: si458 <simonsmith5521@gmail.com>

si458 committed May 31, 2026 at 19:59 UTC 222cb6449480182ce717c650905ec31bafa91f26
3 files changed +20 -16
agents/meshcore.js
+12 -8
@@ -1716,7 +1716,7 @@ function handleServerCommand(data) {
1716 sessionid: data.sessionid
1717 });
1718 };
1719 - if (data.value == 'installedapps') {
1719 + if (data.type == 'installedapps') {
1720 if (process.platform == 'win32') {
1721 try {
1722 if (require('win-info').installedApps) {
@@ -1738,7 +1738,7 @@ function handleServerCommand(data) {
1738 } else {
1739 sendSoftwareResponse({ success: false, error: "Not supported" });
1740 }
1741 - } else if (data.value == 'installedstoreapps') {
1741 + } else if (data.type == 'installedstoreapps') {
1742 if (process.platform != 'win32') {
1743 sendSoftwareResponse({ success: false, error: "Installed Store Apps is only supported on Windows devices" });
1744 return;
@@ -1748,17 +1748,18 @@ function handleServerCommand(data) {
1748 require('win-info').installedStoreApps().then(sendSoftwareResponse).catch(function(e) { sendSoftwareResponse({ error: e.toString() }); });
1749 }
1750 } catch (e) { sendSoftwareResponse({ error: e.toString() }); }
1751 - } else if (typeof data.value === 'string' && data.value.indexOf('uninstallapp ') === 0) {
1751 + } else if (data.type == 'uninstallapp' && (typeof data.value == 'string' && data.value != '')) {
1752 if (process.platform != 'win32') {
1753 sendSoftwareResponse({ success: false, error: "Uninstall is only supported on Windows devices" });
1754 return;
1755 }
1756 - var base64Cmd = data.value.substring(13).trim();
1756 + var base64Cmd = data.value.trim();
1757 var uninstallCmd = '';
1758 try {
1759 var b = Buffer.from(base64Cmd, 'base64');
1760 var decoded = b.toString();
1761 - if (decoded && decoded.length > 0 && decoded.indexOf(':') >= 0) { uninstallCmd = decoded; } else { uninstallCmd = base64Cmd; }
1761 + var lc = decoded ? decoded.toLowerCase() : '';
1762 + if (decoded && decoded.length > 0 && (lc.indexOf('msiexec') >= 0 || lc.indexOf('.exe') >= 0)) { uninstallCmd = decoded; } else { uninstallCmd = base64Cmd; }
1763 } catch (e) { uninstallCmd = base64Cmd; }
1764 if (!uninstallCmd || uninstallCmd.trim() === '' || uninstallCmd.trim() === '\\') {
1765 sendSoftwareResponse({ success: false, error: 'No valid uninstall command available' });
@@ -1781,6 +1782,7 @@ function handleServerCommand(data) {
1782 writeLog('UNINSTALL START - Command: ' + uninstallCmd.replace(/\\/g, '/'));
1783 var originalCmd = uninstallCmd;
1784 if (uninstallCmd.toLowerCase().indexOf('msiexec') >= 0) {
1785 + uninstallCmd = uninstallCmd.replace(/\/I\s*(\{[^}]+\})/gi, '/X $1'); // change /I to /X for uninstall, fixes 7zip example
1786 uninstallCmd = uninstallCmd.replace(/\/q[nbrf]?/gi, '');
1787 if (uninstallCmd.indexOf('/QN') < 0) { uninstallCmd = uninstallCmd + ' /QN /norestart'; }
1788 } else {
@@ -1807,12 +1809,12 @@ function handleServerCommand(data) {
1809 sendSoftwareResponse({ error: ex.toString() });
1810 }
1811 }
1810 - } else if (typeof data.value === 'string' && data.value.indexOf('uninstallstoreapp ') === 0) {
1812 + } else if (data.type == 'uninstallstoreapp' && (typeof data.value === 'string' && data.value != '')) {
1813 if (process.platform != 'win32') {
1814 sendSoftwareResponse({ success: false, error: "Uninstall is only supported on Windows devices" });
1815 return;
1816 }
1815 - var rawName = data.value.substring(18).trim();
1817 + var rawName = data.value.trim();
1818 var packageName = rawName.replace(/"/g, "").replace(/'/g, "");
1819 var logDir = (process.env['ProgramData'] || 'C:\\ProgramData') + '\\MeshAgent';
1820 try { if (!require('fs').existsSync(logDir)) { require('fs').mkdirSync(logDir); } } catch (e) { }
@@ -6102,7 +6104,8 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
6104 try {
6105 var b = Buffer.from(base64Cmd, 'base64');
6106 var decoded = b.toString();
6105 - if (decoded && decoded.length > 0 && decoded.indexOf(':') >= 0) {
6107 + var lc = decoded ? decoded.toLowerCase() : '';
6108 + if (decoded && decoded.length > 0 && (lc.indexOf('msiexec') >= 0 || lc.indexOf('.exe') >= 0)) {
6109 uninstallCmd = decoded;
6110 } else {
6111 uninstallCmd = base64Cmd;
@@ -6136,6 +6139,7 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
6139 writeLog('UNINSTALL START - Command: ' + uninstallCmd.replace(/\\/g, '/'));
6140 var originalCmd = uninstallCmd;
6141 if (uninstallCmd.toLowerCase().indexOf('msiexec') >= 0) {
6142 + uninstallCmd = uninstallCmd.replace(/\/I\s*(\{[^}]+\})/gi, '/X $1');
6143 uninstallCmd = uninstallCmd.replace(/\/q[nbrf]?/gi, '');
6144 if (uninstallCmd.indexOf('/QN') < 0) {
6145 uninstallCmd = uninstallCmd + ' /QN /norestart';
views/default.handlebars
+4 -4
@@ -12925,7 +12925,7 @@
12925 installedAppsLoadingType = 0;
12926 return;
12927 }
12928 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'installedapps' });
12928 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'installedapps' });
12929 }
12930
12931 function handleInstalledAppsResponse(data) {
@@ -12965,7 +12965,7 @@
12965 installedAppsLoading = true;
12966 installedAppsLoadingType = 2; // Store Apps laden
12967 QH('p18Status', '<span style="color:blue">' + "Loading store apps..." + '</span>');
12968 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'installedstoreapps' });
12968 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'installedstoreapps' });
12969 }
12970
12971 function toggleStoreApps() {
@@ -13131,7 +13131,7 @@
13131 setDialogMode(2, "Uninstall Software", 3, function() {
13132 QH('p18Status', '<span style="color:blue">' + "Uninstalling..." + '</span>');
13133 var base64Cmd = btoa(unescape(encodeURIComponent(cmd))); //Use Base64 encoding to avoid special character problems.
13134 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'uninstallapp ' + base64Cmd });
13134 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'uninstallapp', value: base64Cmd });
13135 setTimeout(function() { QH('p18Status', "Uninstall started. Click Refresh to update"); }, 2000);
13136 }, dialogContent);
13137 }
@@ -13146,7 +13146,7 @@
13146 dialogContent += '</div>';
13147 setDialogMode(2, "Remove Store App", 3, function() {
13148 QH('p18Status', '<span style="color:blue">' + "Removing..." + '</span>');
13149 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'uninstallstoreapp "' + cmd.replace(/"/g, '\\"') + '"' });
13149 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'uninstallstoreapp', value: '"' + cmd.replace(/"/g, '\\"') + '"' });
13150 setTimeout(function() { QH('p18Status', "Remove command sent. Click Refresh to update"); }, 2000);
13151 }, dialogContent);
13152 }
views/default3.handlebars
+4 -4
@@ -14819,7 +14819,7 @@
14819 installedAppsLoadingType = 0;
14820 return;
14821 }
14822 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'installedapps'});
14822 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'installedapps'});
14823 }
14824
14825 function handleInstalledAppsResponse(data) {
@@ -14859,7 +14859,7 @@
14859 installedAppsLoading = true;
14860 installedAppsLoadingType = 2;
14861 QH('p18Status', '<span style="color:blue">' + "Loading store apps..." + '</span>');
14862 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'installedstoreapps' });
14862 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'installedstoreapps' });
14863 }
14864
14865 function toggleStoreApps() {
@@ -15026,7 +15026,7 @@
15026 showModal('xxAddAgentModal', 'idx_dlgOkButton', function() {
15027 QH('p18Status', '<span style="color:blue">' + "Uninstalling..." + '</span>');
15028 var base64Cmd = btoa(unescape(encodeURIComponent(cmd))); //Use Base64 encoding to avoid special character problems.
15029 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'uninstallapp ' + base64Cmd });
15029 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'uninstallapp', value: base64Cmd });
15030 setTimeout(function() { QH('p18Status', "Uninstall started. Click Refresh to update"); }, 2000);
15031 });
15032 }
@@ -15042,7 +15042,7 @@
15042 setModalContent('xxAddAgent', "Remove Store App", dialogContent);
15043 showModal('xxAddAgentModal', 'idx_dlgOkButton', function() {
15044 QH('p18Status', '<span style="color:blue">' + "Removing..." + '</span>');
15045 - meshserver.send({ action: 'software', nodeid: currentNode._id, value: 'uninstallstoreapp "' + cmd.replace(/"/g, '\\"') + '"' });
15045 + meshserver.send({ action: 'software', nodeid: currentNode._id, type: 'uninstallstoreapp', value: '"' + cmd.replace(/"/g, '\\"') + '"' });
15046 setTimeout(function() { QH('p18Status', "Remove command sent. Click Refresh to update"); }, 2000);
15047 });
15048 }