首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET 4/水晶报告问题还有其他解决方案吗?

.NET 4/水晶报告问题还有其他解决方案吗?
EN

Stack Overflow用户
提问于 2014-07-16 15:56:23
回答 1查看 663关注 0票数 1

无法加载文件或程序集“file:///C:\Program文件\SAP\ .NET Framework4.0的水晶报表\公用\SAP BusinessObjects企业XI 4.0\win32_x86\dotnet1\crdb_adoplus.dll”或其依赖项之一。系统找不到指定的文件。

我知道,此水晶报告/ .NET 4错误的公认解决方案/黑客是Visual项目的.config文件中的以下代码。

代码语言:javascript
复制
<startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>

还有其他已知的解决方案吗?有人告诉我,在我们的系统上实施这个方案是不可接受的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-16 16:00:03

我首先要问,为何这是不可接受的呢?您的应用程序是否从其他可执行文件获取其配置,比如MMC管理单元,它需要添加到mmc.exe.config或由dllhost.exe加载的COM+应用程序中,因此需要修改dllhost.exe.config?如果不是,我不明白为什么您不能修改自己的应用程序配置。

就像我看到的那样

1.您可能可以按这篇博客文章中所概述的那样,按编程方式设置此值。

应该注意的是,作者(受人尊敬的SO成员)在博客文章中警告:

我强烈建议使用使用app.config的官方方法来设置此策略。

我建议你充分阅读这篇文章,但为了避免发布链接答案和避免链接腐烂,如果博客曾经移动,一些高亮的直接从博客中被提出来是包括在内的。在该员额中,提出的解决办法是:

代码语言:javascript
复制
public static class RuntimePolicyHelper
{
    public static bool LegacyV2RuntimeEnabledSuccessfully { get; private set; }

    static RuntimePolicyHelper()
    {
        ICLRRuntimeInfo clrRuntimeInfo =
            (ICLRRuntimeInfo)RuntimeEnvironment.GetRuntimeInterfaceAsObject(
                Guid.Empty, 
                typeof(ICLRRuntimeInfo).GUID);
        try
        {
            clrRuntimeInfo.BindAsLegacyV2Runtime();
            LegacyV2RuntimeEnabledSuccessfully = true;
        }
        catch (COMException)
        {
            // This occurs with an HRESULT meaning 
            // "A different runtime was already bound to the legacy CLR version 2 activation policy."
            LegacyV2RuntimeEnabledSuccessfully = false;
        }
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("BD39D1D2-BA2F-486A-89B0-B4B0CB466891")]
    private interface ICLRRuntimeInfo
    {
        void xGetVersionString();
        void xGetRuntimeDirectory();
        void xIsLoaded();
        void xIsLoadable();
        void xLoadErrorString();
        void xLoadLibrary();
        void xGetProcAddress();
        void xGetInterface();
        void xSetDefaultStartupFlags();
        void xGetDefaultStartupFlags();

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void BindAsLegacyV2Runtime();
    }
}

这篇文章给出了使用它的例子:

举一个简单的音频播放器为例。下面的代码显示了如何在运行时正确地使用它,只有在成功的情况下才使用“本机”API,如果失败,则使用回退(或引发更好的异常):

代码语言:javascript
复制
public class AudioPlayer
{
    private IAudioEngine audioEngine;

    public AudioPlayer()
    {
        if (RuntimePolicyHelper.LegacyV2RuntimeEnabledSuccessfully)
        {
            // This will load a CLR 2 mixed mode assembly
            this.audioEngine = new AudioEngineNative();
        }
        else
        {
            this.audioEngine = new AudioEngineManaged();
        }
    }

    public void Play(string filename)
    {
        this.audioEngine.Play(filename);
    }
}

现在-警告:这种方法可以工作,但我将非常犹豫地使用它在面向公众的生产代码,特别是在任何东西,除了初始化您自己的应用程序。虽然这在库中是有效的,但是使用它有一个非常糟糕的副作用:您可以以一种非常隐藏和不明显的方式更改正在执行的应用程序的运行时策略。

2.您还可以使用.net v2编译您的应用程序。

然后,它应该能够加载旧的组件。这个选择是否更可以接受呢?

3.获取要加载的组件的更新版本。

我不知道你在这方面会走多远:)。

4.尝试在组件上使用反编译程序,然后针对新版本的框架重新编译。

这可能并不容易,甚至可能是不合法的。在尝试此操作之前,请检查您的许可证协议。这可能也不太合适,但我只是把它作为一种选择。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24785346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档