在卸载之前需要winforms app关闭

时间:2012-05-19 05:37:18

标签: .net winforms windows-installer uninstall

答案可能涉及一个自定义卸载操作,但它看起来像是一个很大的问题,而且每个应用程序都需要这样的东西,所以我想我会看到是否有一些我很想丢失的东西。

我使用C#,Winform项目在Visual Studio 2008中创建了几个项目。一个使用一次性安装,一个使用安装项目。它们都允许您在卸载时保持应用程序运行。在Windows 7上,您会收到警告,但可以选择让它继续运行...在XP上甚至没有警告。

叫我疯了,但想到我的所有程序文件都被删除了,而我的应用程序仍在运行,听起来根本就不是一个好的设计。想到GPF的记忆,或者.NET使用延迟加载DLL的方式,当DLL需要加载并且消失时也可能是一个问题。

如果您的应用仍然在运行,是否有一种不允许卸载的简单方法?

我正在使用C#,但我正在使用VB.NET单实例类来确保我的应用程序只运行一次,所以可能会利用这一点而不是创建互斥锁来检查?

此外,我的应用只允许“每用户”安装,而不是“所有用户”,所以我不必担心我的应用程序在另一个会话中运行(如果是,可以保持运行,因为它应该是100%自己的副本。)

编辑:由于我没有找到任何其他内容,我已经尝试了互斥锁的想法,但它无效。这是我的代码:

在应用程序中,我有这个来创建命名的互斥锁并在应用程序运行时保持活动状态:

        System.Threading.Mutex m = new System.Threading.Mutex(true, "SafeShare");

        SingleInstanceApplication.Run(TabForm, NewInstanceHandler);

        GC.KeepAlive(m);

在卸载操作中,我将其循环直到它们退出(因为它似乎不容易提供取消选项):

            while (true)
            {
                bool createdNew;
                System.Threading.Mutex m = new System.Threading.Mutex(true, "SafeShare", out createdNew);
                m.ReleaseMutex();
                if (createdNew)
                    break;
                MessageBox.Show(null,"Close XXX and click OK to continue uninstall.","Uninstall");
            }

createdNew从未在卸载操作中设置,几乎就像它在不同的会话下运行一样。我没有尝试将Global \添加到互斥锁名称,但这对我的应用程序来说无法正常工作,因为我按用户安装,所以一个安装应该能够继续在另一个会话上运行,即使卸载了一个。 / p>

1 个答案:

答案 0 :(得分:0)

简短的回答是没有简单的方法可以做到这一点,因为这不是微软希望你做的事情。

我的回答确实最终使用了互斥锁,一旦我得到了正确的代码,它似乎工作正常。

在我做的应用程序中:

System.Threading.Mutex m = new System.Threading.Mutex(true, "MyMutexNameHere");
SingleInstanceApplication.Run(TabForm, NewInstanceHandler);
GC.KeepAlive(m); 

SingleInstanceApplication.Run行运行你的应用程序,我正在使用VB.NET框架。

在我执行的自定义卸载操作中:

while (true)
{
   bool createdNew;
   System.Threading.Mutex m = new System.Threading.Mutex(true, "MyMutexNameHere", out createdNew);
   m.Close();
   if (createdNew)
      break;
   MessageBox.Show(null,"Close XXX and click OK to continue uninstall.","Uninstall");
}    

起初我使用m.ReleaseMutex()而不是m.Close(),我发现这是因为我没有拥有互斥锁而抛出异常。关闭是我应该使用的,只是为了确保我的副本在我再次检查之前关闭(否则createNew永远不会是真的,如果第一次不是真的那样)。