.net - 如何强制 WPF 使用使用程序集强名称的资源 URI?啊!

标签 .net wpf xaml resources strongname

好的,这真的很烦人,我之前注意到 WPF 生成的用于加载 XAML 资源的代码似乎没有使用强名称,因此对于需要支持并行版本的 WPF 程序集的场景可能会出现问题。

事实证明是这种情况,它现在给我带来了问题 - 我有一个插件系统,它应该支持并排安装插件,这些插件的不同之处仅在于它们的版本号(它们的程序集版本)。这当然可以由 .NET 支持,因为即使它们具有相同的 DLL 文件名,程序集也被确定具有不同的身份,前提是它们具有强命名并且具有不同的公钥/私钥或具有不同的程序集版本号。

现在,如果我们查看 Visual Studio 为 windows 和 usercontrols 生成的代码,我们会在自动生成的文件中看到以下内容:

/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;
    System.Uri resourceLocater = new System.Uri("/Sensormatic.AMK1000.Panel;component/views/servicepanelui.xaml", System.UriKind.Relative);

    #line 1 "..\..\..\Views\ServicePanelUI.xaml"
    System.Windows.Application.LoadComponent(this, resourceLocater);

    #line default
    #line hidden
}

请注意创建资源定位器的行 - 它使用的是相对 URI,它没有指定强名称或包含 xaml 资源的程序集的版本。

我想也许 LoadComponent 会检查调用程序集的身份并使用它的公钥和版本详细信息,或者可能检查包含“this”参数类型的程序集的身份。

看起来情况并非如此 - 如果您有两个版本号不同(但文件名相同)的程序集,那么您可以获得 IOException 并显示消息“无法定位资源 X”(例如上面的示例“无法定位资源 'views/servicepanelui .xaml'。

更糟糕的是,我很确定这也意味着具有相同文件名但不同公钥/私钥的程序集(即来自不同发布者)也会导致此错误。

那么,有谁知道如何解决这个问题?如何使 WPF 强名称兼容。

请注意,就我而言,这是一个 WPF 错误。您不必为了避免这种情况而使用 Appdomain 隔离。

最佳答案

我们也遇到了同样的问题,但我们只能在我们的解决方案中为某些特定项目设置程序集版本。

因为我喜欢像 user195275 推荐的那样为build设置版本号的想法,所以我对如何为单个 csproj 文件进行了一些研究。

所以结合以下线程How to read the assemblyversion from assemblyInfo.cs?我们提出了以下解决方案:

<Target Name="BeforeBuild">
    <ReadLinesFromFile File="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs">
        <Output TaskParameter="Lines"
                ItemName="ItemsFromFile"/>
    </ReadLinesFromFile>

    <PropertyGroup>
        <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+)\.(\d+)</Pattern>
        <In>@(ItemsFromFile)</In>
        <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
    </PropertyGroup>

    <CreateProperty Value="$(Out.Remove(0, 28))">
        <Output TaskParameter="Value" PropertyName="AssemblyVersion"/>
    </CreateProperty>
</Target>

它的作用:它从 AssemblyInfo.cs 中解析版本号,并将其设置为 Property,如 Aaron Martens 的回答。这为我们带来了版本号的单点维护。

关于.net - 如何强制 WPF 使用使用程序集强名称的资源 URI?啊!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1453107/

相关文章:

c# - Resharper 在从 XAML 创建属性时创建自动属性

c# - 在 WPF 中,我可以在 2 个按钮之间共享相同的图像资源吗

C# 在运行时获取定义字典的类型

c# - 尝试测试任务时 Moq 出现异常

c# - 在没有 UAC 提示的情况下从 .NET 应用程序执行进程

javascript - 是否存在与Wpf/Silverlight inotifyPropertyChanged方法等效的Knockout Js?

c# - 将 WPF 可视化元素保存为 JPEG

c# - Xtra Grid 在运行时排序数据?

wpf使用定时器动态改变图片源

c# - VisualStateGroup的ViewModel方法事件