You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows桌面应用:基于布尔值阻止卸载的C#实现咨询

阻止Windows桌面MSI应用卸载的C#实现方案

要基于布尔值控制应用卸载,核心是拦截Windows Installer的卸载流程,或监控卸载相关系统事件。需注意:Windows系统有自身权限与保护机制,无法做到100%阻止(如用户使用管理员权限、第三方卸载工具等场景),但可实现常规场景下的拦截。


方案1:MSI自定义动作(推荐,与安装包集成)

通过MSI的自定义动作,在卸载序列启动前读取布尔值配置,判断是否终止卸载。

步骤与代码示例

  1. 新建C#自定义动作项目,引用Microsoft.Deployment.WindowsInstaller(可通过NuGet安装Microsoft.Deployment.WindowsInstaller包)。
  2. 编写拦截卸载的代码:
using Microsoft.Deployment.WindowsInstaller;

public class CustomActions
{
    [CustomAction]
    public static ActionResult BlockUninstall(Session session)
    {
        // 从注册表读取控制卸载的布尔值(自定义注册表路径)
        bool allowUninstall = true;
        using (var regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\YourAppIdentifier"))
        {
            if (regKey != null)
            {
                var value = regKey.GetValue("AllowUninstall");
                allowUninstall = value != null && (bool)value;
            }
        }

        if (!allowUninstall)
        {
            session.Log("Uninstall blocked by configuration");
            // 弹出错误提示
            session.Message(InstallMessage.Error, new Record(1) { FormatString = "当前应用禁止卸载,请联系管理员。" });
            return ActionResult.Failure;
        }

        return ActionResult.Success;
    }
}
  1. 将自定义动作集成到MSI包(以WiX为例):
    在WiX的Product节点中添加配置,确保卸载前执行自定义动作:
<CustomAction Id="BlockUninstall" BinaryKey="CustomActionsDll" DllEntry="BlockUninstall" Execute="immediate" Return="check" />
<InstallExecuteSequence>
  <Custom Action="BlockUninstall" Before="RemoveFiles">NOT Installed</Custom>
</InstallExecuteSequence>

方案2:后台监控服务(独立程序,适合已安装应用)

编写Windows服务,监控msiexec.exe的启动事件,当检测到自身应用的卸载请求时,根据布尔值终止进程。

代码示例

using System;
using System.ServiceProcess;
using System.Diagnostics;
using System.Management;
using Microsoft.Win32;

namespace UninstallMonitorService
{
    public partial class UninstallMonitor : ServiceBase
    {
        private ManagementEventWatcher _processWatcher;

        public UninstallMonitor()
        {
            InitializeComponent();
            InitializeWatcher();
        }

        private void InitializeWatcher()
        {
            // 监控msiexec.exe启动事件
            var query = new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'msiexec.exe'");
            _processWatcher = new ManagementEventWatcher(query);
            _processWatcher.EventArrived += OnUninstallAttempt;
        }

        protected override void OnStart(string[] args)
        {
            _processWatcher.Start();
        }

        protected override void OnStop()
        {
            _processWatcher.Stop();
        }

        private void OnUninstallAttempt(object sender, EventArrivedEventArgs e)
        {
            var processId = int.Parse(e.NewEvent.Properties["ProcessId"].Value.ToString());
            using (var process = Process.GetProcessById(processId))
            {
                // 替换为你的MSI产品GUID
                var targetProductCode = "{YOUR-APP-PRODUCT-CODE-GUID}";
                if (process.StartInfo.Arguments.Contains("/x") && process.StartInfo.Arguments.Contains(targetProductCode))
                {
                    bool allowUninstall = GetUninstallPermission();
                    if (!allowUninstall)
                    {
                        try
                        {
                            process.Kill();
                            EventLog.WriteEntry("UninstallMonitor", "Uninstall blocked successfully", EventLogEntryType.Information);
                        }
                        catch (Exception ex)
                        {
                            EventLog.WriteEntry("UninstallMonitor", $"Failed to block uninstall: {ex.Message}", EventLogEntryType.Error);
                        }
                    }
                }
            }
        }

        private bool GetUninstallPermission()
        {
            // 从注册表读取布尔配置
            using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\YourAppIdentifier"))
            {
                if (regKey == null) return true;
                var value = regKey.GetValue("AllowUninstall");
                return value != null && (bool)value;
            }
        }
    }
}

注意事项

  • 权限要求:自定义动作与监控服务均需管理员权限才能正常执行,否则无法修改注册表或终止系统进程。
  • 局限性:无法阻止用户通过安全模式、第三方卸载工具或直接删除文件的方式卸载应用。
  • 合规性:阻止卸载可能违反Windows应用规范,建议仅在企业内部场景使用,并提前告知用户。

内容的提问来源于stack exchange,提问作者Elanchezhiyan P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:05:25