发布带有视觉样式的 WPF 应用程序

视觉样式使常见控件的外观能够根据用户选择的主题进行更改。 默认情况下,不会为 Windows Presentation Foundation (WPF) 应用程序启用视觉样式,因此必须手动启用它们。 但是,为 WPF 应用程序启用视觉样式,然后发布解决方案会导致错误。 本主题介绍如何解决此错误,以及如何发布启用了视觉样式的 WPF 应用程序的过程。 有关视觉样式的详细信息,请参阅 视觉样式概述。 有关错误消息的详细信息,请参阅 ClickOnce 部署中的特定错误疑难解答

若要解决错误并发布解决方案,必须执行以下任务:

发布未启用视觉样式的解决方案

  1. 确保你的项目未启用视觉样式。 首先,检查项目的清单文件是否有以下 XML。 然后,如果存在 XML,请将 XML 与注释标记括起来。

    默认情况下,不会启用视觉样式。

    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
        </dependentAssembly>
    </dependency>
    

    以下过程演示如何打开与项目关联的清单文件。

    在 Visual Basic 项目中打开清单文件

    1. 在菜单栏上,选择 ProjectProjectName属性,其中 ProjectName 是 WPF 项目的名称。

      WPF 项目的属性页会出现。

    2. “应用程序 ”选项卡上,选择“ 查看 Windows 设置”。

      app.manifest 文件将在 代码编辑器中打开。

    在 C# 项目中打开清单文件

    1. 在菜单栏上,选择 ProjectProjectName属性,其中 ProjectName 是 WPF 项目的名称。

      将显示 WPF 项目的属性页。

    2. “应用程序 ”选项卡上,记下清单字段中显示的名称。 这是与您的项目关联的清单文件名称。

      注释

      如果 嵌入带有默认设置的清单创建没有清单的应用程序 出现在清单字段中,则不会启用视觉样式。 如果清单文件的名称显示在清单字段中,请继续执行此过程的下一步。

    3. 解决方案资源管理器中,选择“ 显示所有文件”。

      此按钮显示所有项目项,包括已排除的项目项和通常隐藏的项目项。 清单文件显示为项目元素。

  2. 生成并发布解决方案。 有关如何发布解决方案的详细信息,请参阅 如何:使用发布向导发布 ClickOnce 应用程序

创建清单文件

  1. 将以下 XML 粘贴到记事本文件中。

    此 XML 描述包含支持视觉样式的控件的程序集。

    <?xml version="1.0" encoding="utf-8"?>
    <asmv1:assembly manifestVersion="1.0"
        xmlns="urn:schemas-microsoft-com:asm.v1"
        xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
        xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <dependency>
            <dependentAssembly>
                <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
            </dependentAssembly>
        </dependency>
    </asmv1:assembly>
    
  2. 在记事本中,单击“ 文件”,然后单击“ 另存为”。

  3. 在“ 另存为 ”对话框中的“ 另存为类型 ”下拉列表中,选择“ 所有文件”。

  4. “文件名 ”框中,将该文件命名,并将 .manifest 追加到文件名的末尾。 例如: themes.manifest

  5. 选择“ 浏览文件夹 ”按钮,选择任意文件夹,然后单击“ 保存”。

    注释

    其余过程假定此文件的名称为 themes.manifest ,并将该文件保存到计算机上的 C:\temp 目录。

将清单文件嵌入已发布解决方案的可执行文件中

  1. 打开 Visual Studio 开发人员命令提示符。

    有关如何打开 Visual Studio 开发人员命令提示符的详细信息,请参阅 开发人员命令提示符和开发人员 PowerShell

    注释

    其余步骤对解决方案做出以下假设:

    • 解决方案的名称为 MyWPFProject

    • 解决方案位于以下目录中: %UserProfile%\Documents\Visual Studio version\Projects\

    • 解决方案将发布到以下目录: %UserProfile%\Documents\Visual Studio version\Projects\publish

    • 已发布的应用程序文件的最新版本位于以下目录中: %UserProfile%\Documents\Visual Studio version\Projects\publish\Application Files\WPFApp_1_0_0_0

    无需使用上述名称或目录位置。 上述名称和位置仅用于说明发布解决方案所需的步骤。

  2. 在命令提示符处,更改包含已发布应用程序文件的最新版本的目录的路径。 以下示例演示此步骤。

    cd "%UserProfile%\Documents\Visual Studio version\Projects\MyWPFProject\publish\Application Files\WPFApp_1_0_0_0"
    
  3. 在命令提示符下运行以下命令,将清单文件嵌入应用程序的可执行文件中。

    mt -manifest c:\temp\themes.manifest -outputresource:MyWPFApp.exe.deploy
    

对应用程序和部署清单进行签名

  1. 在命令提示符下运行以下命令,从当前目录中的可执行文件中删除 .deploy 扩展名。

    ren MyWPFApp.exe.deploy MyWPFApp.exe
    

    注释

    此示例假定只有一个文件具有 .deploy 文件扩展名。 请确保重命名此目录中扩展名为 .deploy 文件扩展名的所有文件。

  2. 在命令提示符下运行以下命令以对应用程序清单进行签名。

    mage -u MyWPFApp.exe.manifest -cf ..\..\..\MyWPFApp_TemporaryKey.pfx
    

    注释

    此示例假定使用项目的 .pfx 文件对清单进行签名。 如果不对清单进行签名,可以省略 -cf 此示例中使用的参数。 如果要使用需要密码的证书对清单进行签名,请 -password 指定选项(For example: mage -u MyWPFApp.exe.manifest -cf ..\..\..\MyWPFApp_TemporaryKey.pfx - password Password)。

  3. 在命令提示符下运行以下命令,将 .deploy 扩展名添加到你在此过程上一步中重命名的文件的名称。

    ren MyWPFApp.exe MyWPFApp.exe.deploy
    

    注释

    此示例假定只有一个文件具有 .deploy 文件扩展名。 请确保重命名以前具有 .deploy 文件扩展名的此目录中的所有文件。

  4. 在命令提示符下运行以下命令,对部署清单进行签名。

    mage -u ..\..\MyWPFApp.application -appm MyWPFApp.exe.manifest -cf ..\..\..\MyWPFApp_TemporaryKey.pfx
    

    注释

    此示例假定使用项目的 .pfx 文件对清单进行签名。 如果不对清单进行签名,可以省略 -cf 此示例中使用的参数。 如果要使用需要密码的证书对清单进行签名,请指定-password该选项,如以下示例所示:For example: mage -u MyWPFApp.exe.manifest -cf ..\..\..\MyWPFApp_TemporaryKey.pfx - password Password

    执行这些步骤后,可以将已发布的文件移动到希望最终用户从中安装应用程序的位置。 如果打算经常更新解决方案,则可以将这些命令移动到脚本中,并在每次发布新版本时运行该脚本。