安装项目不会替换程序集文件

发布于 2024-09-30 02:52:12 字数 825 浏览 2 评论 0原文

  1. 我有一个 Windows 应用程序项目 (A.exe) 调用另一个项目 类库 (B.dll)。

  2. A.exe 有一个按钮 (myButton) 从 B.dll 调用 Method1 方法。

  3. 安装我创建的应用程序 安装项目 ASetup.vdproj,其 主要输出是项目 A。

  4. 编译设置后, 安装运行时无需任何 问题,当 A.exe 启动时,我 单击 myButton,应用程序给出 没有错误。

  5. 然后我更改了 B.dll 并添加了新的 方法Method2。

  6. myButton 现在正在调用 Method2 B.dll 而不是 Method1。

  7. 我增加了A.exe的版本并且 增加版本号 ASetup.vdproj,但不增加 B.dll 的版本。

  8. 安装应用程序后我 注意到我有两个安装 控制面板中的A.exe ->添加 / 删除程序。

  9. 运行 A.exe 并单击时 myButton 我收到一个错误,“ 方法 Method2 未找到 B.dll”,这意味着安装程序确实 期间不替换B.dll 安装。

  10. 我运行了卸载,我注意到 文件没有被删除 从磁盘。

我的问题是:

为什么第二次安装没有更新B.dll? 如果增加B.dll的版本,安装时B.dll会被替换,但问题是我当前的项目有很多外部程序集,很难控制它们是否被修改。基本上,我想要的是在每次安装中替换所有程序集文件。

我等待大家的反馈。 感谢大家的关注。

  1. I have a Windows Application project
    (A.exe) that calls another project
    Class Library (B.dll).

  2. A.exe has a button (myButton) that
    calls the method Method1 from B.dll.

  3. To install the application I created
    a Setup project ASetup.vdproj, whose
    Primary Output is project A.

  4. After compiling the setup, the
    installation runs without any
    problems, when A.exe starts and I
    click myButton, the aplication gives
    no error.

  5. Then I changed B.dll and added a new
    method Method2.

  6. myButton is now calling Method2 from
    B.dll instead of Method1.

  7. I increased the version of A.exe and
    increment the version of
    ASetup.vdproj, but do not increase
    the version of B.dll.

  8. After installing the application I
    noticed I had two installations of
    A.exe in Control Panel -> Add /
    Remove Programmes.

  9. When running A.exe and click
    myButton I obtain an error, "The
    method Method2 was not found in
    B.dll", it means that the setup does
    not replace B.dll during
    installation.

  10. I ran the uninstall and I noticed
    that the files were not removed
    from disk.

My question is:

Why doesn’t the second installation update B.dll?
If the version of B.dll is incremented, B.dll will be replaced during the installation, but the problem is that my current project has many external assemblies, which is difficult to control if they have been modified or not. Basically, what I want is that all assembly files are replaced in each installation.

I await feedback from all of you.
Thank you for all the attention.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

亢潮 2024-10-07 02:52:12

“添加/删除程序”中的 2 个条目告诉我,您更改了 ProductCode 属性,但升级表中没有有效行来正确定义主要升级。 MSI 将其视为恰好安装到同一目录的 2 个不同产品。当您卸载这两个产品之一时,文件将保留,直到您卸载另一个产品。

DLL 未被覆盖表明您没有将 AssemblyFileVersion 属性从一个版本更改为另一个版本。第一个安装复制 1.0.0.0,第二个安装显示“1.0.0.0 已经存在,此处无需执行任何操作”并跳过它。

The 2 entries in Add/Remove Programs tells me that you changed the ProductCode property but didn't have a valid row in the Upgrade Table to properly define a Major Upgrade. MSI treats this as 2 different products that happen to get installed to the same directory. When you uninstall one of the two products the files remain until you uninstall the other product.

The DLL not being overwritten suggests to me that you didn't change the AssemblyFileVersion attribute from one build to another. The first install copies in 1.0.0.0 and the second install says "1.0.0.0 is already there, nothing to do here" and skips it.

つ低調成傷 2024-10-07 02:52:12

除了@Christopher Painter提到的问题之外,很可能还有另一个问题:使用Visual Studio(2008)创建的安装项目只会在版本号增加的情况下替换文件。显而易见的解决方案是只增加所有版本号;然而,这可能并不总是您想要的。

.msi 文件的行为基本上由 RemoveExistingProducts 动作被执行。使用 VS 2008 创建的安装程序会在安装新产品后安排此操作。版本尚未增加的已修改程序集因此不会被替换。此线程中描述了有关更新行为的更多详细信息:

删除以前的版本=True但以前的版本不会从目标机器中删除

要更改行为,您可以修补创建的 .msi 文件,以便 RemoveExistingProducts 操作在新产品安装之前执行(如果您使用 Visual Studio 创建安装程序,这实际上是行为) 2005)。例如,可以使用作为后构建步骤运行的小型 VBScript 来完成修补:

Dim objInstaller
Dim objDatabase
Dim objView
Dim objResult

Dim strPathMsi 

If WScript.Arguments.Count <> 1 Then
    WScript.Echo "Usage: cscript fixRemovePreviousVersions.vbs <path to MSI>"
    WScript.Quit -1
End If

strPathMsi = WScript.Arguments(0)

Set objInstaller = CreateObject("WindowsInstaller.Installer")
Set objDatabase = objInstaller.OpenDatabase(strPathMsi, 1)
Set objView = objDatabase.OpenView("UPDATE InstallExecuteSequence SET Sequence=1450 WHERE Action='RemoveExistingProducts'")

WScript.Echo "Patching install sequence: UPDATE InstallExecuteSequence SET Sequence=1450 WHERE Action='RemoveExistingProducts'"
objView.Execute
objDatabase.Commit

WScript.Quit 0

Besides the problem mentioned by @Christopher Painter, there is most likely another problem: The setup project created with Visual Studio (2008) will only replace files if the version number has been incremented. The obvious solution would be to just increment all version numbers; however, this might not always be what you want.

The behavior of the .msi file is basically determined by the moment when the RemoveExistingProducts action is executed. Installers created with VS 2008 schedule this action after the new product has been installed. Modified assemblies whose version has not been incremented therefore don't get replaced. Some more details about the update behavior are described in this thread:

RemovePreviousVersions=True but previous version is not removed from the target machine

To change the behavior, you can patch the created .msi file so that the RemoveExistingProducts action is executed before the new product gets installed (this actually has been the behavior if you created the setup with Visual Studio 2005). Patching can e.g. be done using a small VBScript that runs as a post-built step:

Dim objInstaller
Dim objDatabase
Dim objView
Dim objResult

Dim strPathMsi 

If WScript.Arguments.Count <> 1 Then
    WScript.Echo "Usage: cscript fixRemovePreviousVersions.vbs <path to MSI>"
    WScript.Quit -1
End If

strPathMsi = WScript.Arguments(0)

Set objInstaller = CreateObject("WindowsInstaller.Installer")
Set objDatabase = objInstaller.OpenDatabase(strPathMsi, 1)
Set objView = objDatabase.OpenView("UPDATE InstallExecuteSequence SET Sequence=1450 WHERE Action='RemoveExistingProducts'")

WScript.Echo "Patching install sequence: UPDATE InstallExecuteSequence SET Sequence=1450 WHERE Action='RemoveExistingProducts'"
objView.Execute
objDatabase.Commit

WScript.Quit 0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文