Wix 卸载时不删除文件

发布于 2024-12-06 08:16:19 字数 6429 浏览 1 评论 0原文

我看过其他人对此事的疑问,但我无法让它为我工作。我正在尝试习惯 Wix,这样我们就可以迁移我们的 vdproj(我觉得我们已经向前迈出了 1 步,又退了 4 步……对于 Wix,最基本的事情已经变得完全不平凡了……但我确实看到了为建筑安装人员提供成熟的声明性标记的价值)。

我在 SharpDevelop 的 wixproj 中有以下 wxs。

安装作品。卸载不执行任何操作,并保留安装文件夹和 dll。有什么问题吗?

文件.wxs:

<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="TARGETDIR">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="Client">
                    <Component Id="InteropDll" Guid="AD09F8B9-80A0-46E6-9E36-9618E2023D66" DiskId="1">
                        <File Id="Interop.dll" Name="Interop.dll" Source="..\Interop\bin\$(var.Configuration)\Interop.dll" KeyPath="yes" />
                        <RemoveFile Id="RemoveInterop.dll" Name="Interop.dll" On="uninstall" />
                    </Component>
                </Directory>
            </Directory>
        </DirectoryRef>
    </Fragment>
</Wix>

设置.wxs:

<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*"
        Name="Client Setup"
        Language="1033"
        Version="1.0.0.0"
        UpgradeCode="4A88A3AD-7CB6-46FB-B2FD-F4EADE0218F8"
        Manufacturer="Client Setup">
        <Package Description="#Description"
            Comments="Comments"
            InstallerVersion="200"
            Compressed="yes"/>
        <!--
            Source media for the installation. 
            Specifies a single cab file to be embedded in the installer's .msi. 
        -->
        <Media Id="1" Cabinet="contents.cab" EmbedCab="yes" CompressionLevel="high"/>

        <!-- Installation directory and files are defined in Files.wxs -->
        <Directory Id="TARGETDIR" Name="SourceDir"/>

        <Feature Id="Complete"
                 Title="Client Setup"
                 Description="Client Setup"
                 Level="1">
            <ComponentRef Id="InteropDll" />
        </Feature>

        <!-- 
            Using the Wix UI library

            WixUI_InstallDir does not allow the user to choose 
            features but adds a dialog to let the user choose a 
            directory where the product will be installed
        -->
        <Property Id="WIXUI_INSTALLDIR">INSTALLDIR</Property>

        <UI Id="WixUI_InstallDir">
            <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
            <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
            <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />

            <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
            <Property Id="WixUI_Mode" Value="InstallDir" />

            <DialogRef Id="BrowseDlg" />
            <DialogRef Id="DiskCostDlg" />
            <DialogRef Id="ErrorDlg" />
            <DialogRef Id="FatalError" />
            <DialogRef Id="FilesInUse" />
            <DialogRef Id="MsiRMFilesInUse" />
            <DialogRef Id="PrepareDlg" />
            <DialogRef Id="ProgressDlg" />
            <DialogRef Id="ResumeDlg" />
            <DialogRef Id="UserExit" />

            <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
            <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>

            <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

            <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
            <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>

            <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
            <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>

            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>

            <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>

            <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>

            <Property Id="ARPNOMODIFY" Value="1" />
        </UI>

        <UIRef Id="WixUI_Common" />
    </Product>
</Wix>

I've seen others' questions on this matter, but I can't make it work for me. I'm trying to get used to Wix so we can migrate our vdproj's (I feel like we've taken 1 step forward and 4 steps back here...the most basic of things have become completely non-trivial with Wix...but I do see value in having a fully fledged declarative markup for building installers).

I have the following wxs in a wixproj in SharpDevelop.

Install works. Uninstall does nothing and leaves the install folder and dll in place. What's the problem?

Files.wxs:

<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="TARGETDIR">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="Client">
                    <Component Id="InteropDll" Guid="AD09F8B9-80A0-46E6-9E36-9618E2023D66" DiskId="1">
                        <File Id="Interop.dll" Name="Interop.dll" Source="..\Interop\bin\$(var.Configuration)\Interop.dll" KeyPath="yes" />
                        <RemoveFile Id="RemoveInterop.dll" Name="Interop.dll" On="uninstall" />
                    </Component>
                </Directory>
            </Directory>
        </DirectoryRef>
    </Fragment>
</Wix>

Setup.wxs:

<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*"
        Name="Client Setup"
        Language="1033"
        Version="1.0.0.0"
        UpgradeCode="4A88A3AD-7CB6-46FB-B2FD-F4EADE0218F8"
        Manufacturer="Client Setup">
        <Package Description="#Description"
            Comments="Comments"
            InstallerVersion="200"
            Compressed="yes"/>
        <!--
            Source media for the installation. 
            Specifies a single cab file to be embedded in the installer's .msi. 
        -->
        <Media Id="1" Cabinet="contents.cab" EmbedCab="yes" CompressionLevel="high"/>

        <!-- Installation directory and files are defined in Files.wxs -->
        <Directory Id="TARGETDIR" Name="SourceDir"/>

        <Feature Id="Complete"
                 Title="Client Setup"
                 Description="Client Setup"
                 Level="1">
            <ComponentRef Id="InteropDll" />
        </Feature>

        <!-- 
            Using the Wix UI library

            WixUI_InstallDir does not allow the user to choose 
            features but adds a dialog to let the user choose a 
            directory where the product will be installed
        -->
        <Property Id="WIXUI_INSTALLDIR">INSTALLDIR</Property>

        <UI Id="WixUI_InstallDir">
            <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
            <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
            <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />

            <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
            <Property Id="WixUI_Mode" Value="InstallDir" />

            <DialogRef Id="BrowseDlg" />
            <DialogRef Id="DiskCostDlg" />
            <DialogRef Id="ErrorDlg" />
            <DialogRef Id="FatalError" />
            <DialogRef Id="FilesInUse" />
            <DialogRef Id="MsiRMFilesInUse" />
            <DialogRef Id="PrepareDlg" />
            <DialogRef Id="ProgressDlg" />
            <DialogRef Id="ResumeDlg" />
            <DialogRef Id="UserExit" />

            <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
            <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>

            <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

            <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
            <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>

            <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
            <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>

            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>

            <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>

            <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>

            <Property Id="ARPNOMODIFY" Value="1" />
        </UI>

        <UIRef Id="WixUI_Common" />
    </Product>
</Wix>

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

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

发布评论

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

评论(6

娇妻 2024-12-13 08:16:19

尝试更改未卸载组件的 GUID。我尝试了同样的方法,它对我有用。这可能是因为 GUID 已由某些其他产品在注册表中注册。

原因通常是注册表中的组件引用计数混乱 - 通常在开发过程中发生在开发盒上。由于使用 SharedDllRefCount 概念(传统的非 MSI 引用计数)。

一些技术细节
在 wix 中更改我的组件 GUID? 在干净的虚拟机上进行测试以验证问题是真实的,而不是开发盒问题。更改组件 GUID 可能会产生影响(修补问题等...)。

Try to change the GUID of the components which are not uninstalling. I tried the same and it worked for me. It may be because the GUID is already registered in the registry by some other product.

The cause is generally messed up component reference count in the registry - often it happens on dev-boxes during development. Can also often happen to Installshield packages due to their use of the SharedDllRefCount concept (legacy, non-MSI reference counting).

Some technical details:
Change my component GUID in wix? Test on a clean virtual to verify the problem is real and not a dev-box issue. Changing component GUIDs can have repercussions (patching problems etc...).

薄荷梦 2024-12-13 08:16:19

确保没有其他 MSI 软件包保留您安装的组件。

具体来说,进入控制面板/程序和功能,并确保没有安装“旧”版本的程序。

Make sure that no other MSI packages are keeping your components installed.

Specifically, go into Control Panel / Programs and Features, and make sure that there isn't an "old" version of your program still installed.

俏︾媚 2024-12-13 08:16:19

值得检查以下注册表项以查看您的文件是否已列出。这可能会导致卸载程序忽略这些组件,因为它认为这些组件是共享的。

HKLM\Software\Microsoft\Windows\CurrentVersion\SharedDlls

Would be worth checking the following registry key to see if your files are listed. This can cause the uninstaller to ignore the components as it believes them to be shared.

HKLM\Software\Microsoft\Windows\CurrentVersion\SharedDlls
記憶穿過時間隧道 2024-12-13 08:16:19

我以某种方式使我的项目处于无法卸载每个组件的状态。我不知道怎么办。我编写了一个程序,它将采用 .wixproj 文件并将所有组件 GUID 更改为新的 GUID,并解决了问题(在我手动删除文件之后)。这是基于 user593287 的回答。

参数应该是项目文件的路径。从命令行运行此命令的一个示例是:

GuidFixer.exe MyProject.csproj

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace GuidFixer
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string projectFileName = args[0];
            string path = Path.GetDirectoryName(projectFileName);
            List<string> files = new List<string>();

            XmlDocument projectDocument = new XmlDocument();            
            projectDocument.Load(projectFileName);
            XmlNamespaceManager manager = new XmlNamespaceManager(projectDocument.NameTable);
            manager.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");

            // Finds all of the files included in the project.
            XmlNodeList nodes = projectDocument.SelectNodes("/msbld:Project/msbld:ItemGroup/msbld:Compile", manager);
            foreach (XmlNode node in nodes)
            {
                string fileName = Path.Combine(path, node.Attributes["Include"].Value);
                files.Add(fileName);
            }

            foreach (string fileName in files)
            {
                // Lets only do .wxs files
                if (!Path.GetExtension(fileName).Equals(".wxs", StringComparison.CurrentCulture))
                {
                    continue;
                }

                // This will only update files that aren't readonly, make sure
                // you check out your files from source control before running.
                FileAttributes attributes = File.GetAttributes(fileName);
                if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    continue;
                }

                bool modified = false;

                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = true; // space inside tags are still lost
                doc.Load(fileName);

                foreach (XmlNode node in doc.GetElementsByTagName("Component"))
                {
                    Guid guid = Guid.NewGuid();
                    string value = guid.ToString("B").ToUpper();

                    node.Attributes["Guid"].Value = value;
                    modified = true;
                }

                // Only update files that were modified, to preserve formatting.
                if (modified)
                {
                    doc.Save(fileName);
                }
            }
        }        
    }
}

我在没有测试的情况下对其进行了一些更改,祝你好运,不过它非常简单。

I somehow got my project in the state where every single one of my components couldn't be uninstalled. I have no idea how. I wrote a program that will take a .wixproj file and change all of the component GUIDs to new GUIDs and that solved the issue (after I manually deleted the files). This is based off of user593287's answer.

The argument should be the path to your project file. An example of running this from the command line would be:

GuidFixer.exe MyProject.csproj

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace GuidFixer
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string projectFileName = args[0];
            string path = Path.GetDirectoryName(projectFileName);
            List<string> files = new List<string>();

            XmlDocument projectDocument = new XmlDocument();            
            projectDocument.Load(projectFileName);
            XmlNamespaceManager manager = new XmlNamespaceManager(projectDocument.NameTable);
            manager.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");

            // Finds all of the files included in the project.
            XmlNodeList nodes = projectDocument.SelectNodes("/msbld:Project/msbld:ItemGroup/msbld:Compile", manager);
            foreach (XmlNode node in nodes)
            {
                string fileName = Path.Combine(path, node.Attributes["Include"].Value);
                files.Add(fileName);
            }

            foreach (string fileName in files)
            {
                // Lets only do .wxs files
                if (!Path.GetExtension(fileName).Equals(".wxs", StringComparison.CurrentCulture))
                {
                    continue;
                }

                // This will only update files that aren't readonly, make sure
                // you check out your files from source control before running.
                FileAttributes attributes = File.GetAttributes(fileName);
                if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    continue;
                }

                bool modified = false;

                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = true; // space inside tags are still lost
                doc.Load(fileName);

                foreach (XmlNode node in doc.GetElementsByTagName("Component"))
                {
                    Guid guid = Guid.NewGuid();
                    string value = guid.ToString("B").ToUpper();

                    node.Attributes["Guid"].Value = value;
                    modified = true;
                }

                // Only update files that were modified, to preserve formatting.
                if (modified)
                {
                    doc.Save(fileName);
                }
            }
        }        
    }
}

I made some changes to it without testing it, so good luck, it's pretty straightforward though.

绻影浮沉 2024-12-13 08:16:19

我遇到了类似的问题,当我将所有 guid 转换为大写时,该问题似乎不再存在(按照某些兼容性问题规范的要求)。没有广泛测试这是否真的是问题的解决方案。也许这和之前的答案是一样的。

I encountered a similar problem, which appeard not to be present any more when I converted all guids into uppercase (as required in some specification for compatiblity issues). Did not test exensively whether this was really the solution to the problem. Maybe this is the same as the previous answer.

做个少女永远怀春 2024-12-13 08:16:19

我有类似的问题。我执行了上述所有步骤,但文件不会被卸载,日志也不会表明有任何问题。

删除(出于开发目的,我使用 wxs 将安装位置重新定位到不同的文件夹)之后,

<!--DEBUG: use C:\Laser-Wix\ as base path for now-->
<SetDirectory Id="LaserDir" Value="[WindowsVolume]Laser-WIX" />

只有在我从 wxs 中

文件才真正被删除。希望这对某人有帮助。

I had a similar issue. I did all the above steps, but the files would just not be uninstalled and the log would not indicate that anything was wrong.

Only after I removed

<!--DEBUG: use C:\Laser-Wix\ as base path for now-->
<SetDirectory Id="LaserDir" Value="[WindowsVolume]Laser-WIX" />

from my wxs (which I used to retarget the install location to a different folder for development purposes) the files were actually removed.

Hope this helps someone.

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