如何始终安装功能

How to install a feature always

我的安装程序有一个名为 'MyDatabase' 的功能,它显示一个对话框以接受输入 'server, dbname, user, pwd' 并创建指定的数据库。

第一次安装就可以了。我的要求是每次安装程序 运行 并且选择此 'MyDatabase' 功能时都显示此对话框。用户可以选择每次都创建一个新的数据库。如果数据库存在,它将显示一条消息并退出。

我每次都设法显示对话框,以获取用户的输入。 但它不会安装数据库,除非是第一次。

我怎样才能让它每次都安装?

让我稍微充实一下答案:当您使用 MSI 安装文件时,它使用 组件 GUID 指向它。 MSI 文件认为它是 "owns" 文件,因为你已经给它一个唯一的 GUID,并且会在卸载时愉快地删除文件(这也可能作为主要升级的一部分发生),即使你已经修改了文件并且它充满了用户数据。这是许多设置中非常常见的设计缺陷。

您可以通过将组件设置为永久解决这个问题,如这个答案中所述:MSI Reference Counting: Two products install the same MSIs. However a better concept is to install only read-only files and use your application itself to initialize user-data (ini files, databases, xml settings files, etc...) by copying the read-only templates to the user profile and / or set them via application internal defaults (defined inside the source code). This decouples the deployment of user-settings and data files from the installer avoiding accidental deletion of user data and allowing you to treat all user data setup from the application with the increased flexibility and control this yields. And you avoid complicating your setup, which is more than complex enough as is described here: What is the benefit and real purpose of program installation?

许多人认为他们的设置应该卸载所有用户数据。 不要去那里。我和很多人对此的看法是,用户修改的任何内容都是用户数据,应该单独保留以防用户重新安装产品,或者如果他们想保留数据以便导入其他应用程序。您可以改为记录数据的存储位置,并让人员或系统管理员手动清除它。清除所有用户数据将涉及清除所有用户配置文件。尽管您可以使用诸如 ActiveSetup to accomplish this (another ActiveSetup explanation) 之类的概念,但它通常比其价值更麻烦且容易出错。

要进一步了解组件 GUID 概念,请参阅此答案:Change my component GUID in wix? (recommended read for your use case). Here is a discussion on installsite.net on how to initialize and update userprofile and user data: http://forum.installsite.net/index.php?showtopic=21552

相似的答案(用于跟踪)- 我一遍又一遍地写同样的答案 ;-):

  • C# Deployement retaining files over an installation
  • Always update files in minor upgrade (how to)

就对话框而言,该安装中的对话框将由条件驱动,通常您会在 InstallUISequence 中看到类似欢迎对话框的内容,条件包括 "Not Installed",因此它只显示第一次。因此,这一定是您拥有的导致数据库对话框仅在第一次显示的那种东西。您需要更改对话框的条件和结果流程(下一步、后退等),以便在每次添加功能或实际条件是什么时包含此对话框。

另一半是某处必须有代码,一个自定义操作,并且同样以 运行 为条件,仅在第一次安装时出现类似未安装的情况。所以你会找到它并给它与对话框相同的条件。你可能需要思考 "each time the installer is run" 到底是什么意思?可能不是卸载;维修期间?什么时候删除功能?

这种事情通常(至少根据我的经验)是通过实际的应用程序完成的,而不必再次进行安装。您不会遇到这些 "when do I run it" 问题;编码和调试也更加简单。

我认为不可能每次安装程序 运行 时都安装数据库功能,因为它绑定到组件 GUID。即使我设法显示了 ConnectionStringInputDialog,它在我第二次 运行 同一个安装程序时也没有做任何事情,因为它知道该功能已经安装。

因此,我最终创建了一个单独的 C# Windows 应用程序,并将该应用程序包含在安装程序中。用户可以根据需要多次运行 应用程序,并根据需要运行 sql 脚本(作为资源文件嵌入到应用程序中)。