Hi
I have a problem with getting an error that busineesobjects.licensing.keycodedecoder.dll not found for version 13.0.2000.0.
I am using Crystal Reports for Visual Studio 2010 Support Pack 1 (where I thougt this problem was resolved)
The exception does not show up by default but if I subscribe to the AssemblyResolve event I can see that the common language runtime tries to bind the keycodedecoder assembly and fails.
You can reproduce it by creating a .Net 4 windows forms project in Visual Studio 2010 and have Crystal Reports 2010 SP 1 installed. Here is the code for reproducing it:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using CrystalDecisions.CrystalReports.Engine;
namespace CR2010error
{
public partial class Form1 : Form
{
ReportDocument doc = null;
public Form1()
{
InitializeComponent();
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(QFE);
}
private void button1_Click(object sender, EventArgs e)
{
doc = new ReportDocument();
}
private Assembly QFE(object sender, ResolveEventArgs e)
{
// Format of e.Name: [name-without-exe-and-dll], Version=[version], Culture=[culture], PublicKeyToken=[key]
Assembly assembly = null;
string[] parts = e.Name.Split(',');
if (4 <= parts.Length)
assembly = HandleSignedAssembly(parts[0].ToLower().Trim(), parts[1].ToLower().Trim(), parts[2].ToLower().Trim(), parts[3]);
return assembly;
}
private enum FailType { NoFail, FileNotExist, NoVersionInfo, QfeError, LoadError, };
private Assembly HandleSignedAssembly(string name, string version, string culture, string keyToken)
{
if (name.ToLower().EndsWith("xmlserializers") || name.ToLower().EndsWith(".resources"))
return null;
Assembly assembly = null;
string[] parts1 = version.Split('=');
string wantVer = parts1[1].Trim();
string[] parts2 = wantVer.Split('.');
int wantMajor = Convert.ToInt32(parts2[0]);
int wantMinor = Convert.ToInt32(parts2[1]);
int foundMajor = -1;
int foundMinor = -1;
string path = CreateFullPath(name);
string exception = "";
FileVersionInfo fvi = null;
FailType failType = FailType.NoFail;
try
{
if (!File.Exists(path))
failType = FailType.FileNotExist;
}
catch (Exception e1)
{
failType = FailType.FileNotExist;
exception = e1.Message;
}
if (FailType.NoFail == failType)
{
try
{
fvi = FileVersionInfo.GetVersionInfo(path);
foundMajor = fvi.FileMajorPart;
foundMinor = fvi.FileMinorPart;
}
catch (Exception e2)
{
failType = FailType.NoVersionInfo;
exception = e2.Message;
}
if (null != fvi)
{
if (wantMajor != foundMajor || wantMinor != foundMinor)
failType = FailType.QfeError;
else
{
try
{
assembly = Assembly.LoadFrom(path);
}
catch (Exception e3)
{
failType = FailType.LoadError;
exception = e3.Message;
assembly = null;
}
}
}
}
if (null == assembly)
{
Message_SignedAssembly(failType, exception, path, name, wantVer, null == fvi ? null : fvi.FileVersion);
}
return assembly;
}
private void Message_SignedAssembly(FailType failType, string exception, string path, string nameOfDll, string wantVersion, string foundVersion)
{
StackTrace st;
StackFrame sf = GetOriginatingStackFrame(out st);
string referredBy = "";
if (null != sf)
if (-1 != sf.GetFileLineNumber())
referredBy = string.Format(msgSource1, sf.GetMethod().DeclaringType, sf.GetMethod().Name, sf.GetFileLineNumber(), sf.GetFileColumnNumber());
string reason = "";
if (failType == FailType.FileNotExist)
reason = string.Format(msgReason1, path);
else if (failType == FailType.LoadError)
reason = string.Format(msgReason2, exception);
else if (failType == FailType.NoVersionInfo)
reason = string.Format(msgReason3, exception);
else if (failType == FailType.QfeError)
reason = string.Format(msgReason4, wantVersion, foundVersion);
else
return;
string msg = string.Format(msgBase1, referredBy, nameOfDll, reason);
MessageBox.Show(msg, "QFE Resolver failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
MessageBox.Show("StackTrace: " + st.ToString());
}
private string CreateFullPath(string name)
{
if (name.EndsWith(".resources"))
name = name.Substring(0, name.Length - ".resources".Length);
return AppDomain.CurrentDomain.BaseDirectory + name + ".dll";
}
private StackFrame GetOriginatingStackFrame(out StackTrace st)
{
st = new StackTrace(true);
StackFrame sf = null;
for (int i = st.FrameCount - 1; 0 <= i; --i)
{
StackFrame frame = st.GetFrame(i);
string s = frame.GetMethod().Name;
if (frame.GetMethod().Name == "QFE")
break;
if (null != frame.GetFileName())
sf = frame;
}
return sf;
}
#region Message
static string msgBase1 =
@"The program has failed to resolve a reference to a dll.
Referenced dll is .dll Reason for failing: "; static string msgSource1 = @" Referred by . [:]"; static string msgReason1 = @"The referenced file does not exist. Searched for file: Copy the missing referenced file and retry again."; static string msgReason2 = @"The referenced file cannot be loaded. "; static string msgReason3 = @"Version information could not be obtained from the referenced file. Recompile the referenced file and retry again. "; static string msgReason4 = @"The referenced file is not compatible with the requested version. The requested version was , but the found file has version .
According to the rules of QFE, these versions are not considered to be compatible.
Replace the referenced file with a compatible version and retry.";
#endregion
}
}