Posted 15 January 2020, 6:10 am EST
Hi,
We are having problems when generating Section Reports that use Scripting.
We have an assembly - lets call it ParentAssembly.dll - that has some referenced assemblies - lets call them ChildAssembly1.dll, ChildAssembly2.dll etc…
We have two configurations of our software:
“Complete” - We deploy all the assemblies to the client: ParentAssembly.dll, ChildAssembly1.dll, ChildAssembly2.dll etc…
and
“Partial” - We deploy NOT ALL of the assemblies to the client: e.g. ParentAssembly.dll and ChildAssembly1.dll only (ChildAssembly2.dll and other assemblies are not deployed).
We generate Section Reports from ParentAssembly.dll.
Now it seems that:
- When we generate a report without a scripts then it works in both “Complete” and “Partial” configurations of our software.
- When we generate a report WITH SCRIPTS then it works in “Complete” configuration, BUT IT DOES NOT WORK in “Partial” configuration.
The error that is generated looks like:
Could not load file or assembly ‘XXX, Version=YYY, Culture=neutral, PublicKeyToken=ZZZ’ or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER))
Callstack:
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.AppDomain.Load(AssemblyName assemblyRef)
at GrapeCity.ActiveReports.DDScripting.b__f(AssemblyName asmName)
at System.Linq.Enumerable.WhereSelectArrayIterator
2.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator
1.MoveNext()at System.Collections.Generic.HashSet
1.UnionWith(IEnumerable
1 other)at GrapeCity.ActiveReports.DDScripting.Compile()
at GrapeCity.ActiveReports.DDScripting.#Szb(String methodName, Object parameters, Boolean& success)
at GrapeCity.ActiveReports.SectionReport.#izb()
at GrapeCity.ActiveReports.SectionReport.#1yb(Boolean bDelayedInit)
at GrapeCity.ActiveReports.SectionReport.Run(Boolean syncDocument)
By digging into Active Reports internals it looks like when preparing data for Compile() method you try to load all referenced libraries for the current assembly and when it’s not possible then you propagate the error down the application stack and the report generation fails:
private static IEnumerable #ViV(Assembly assembly)
{
return from location in assembly.GetReferencedAssemblies().Select(delegate(AssemblyName asmName)
{
try
{
return AppDomain.CurrentDomain.Load(asmName).Location;
}
catch
{
throw;
}
})
where !string.IsNullOrEmpty(location)
select location;
}
I understand this approach and it looks logical but it fails our “Partial” deployment strategy. (ChildAssembly2.dll will NEVER be loaded in our application as there are no “entry points” in the application that would trigger loading ChildAssembly2.dll - It’s only Active Reports scripting engine that is trying to load this assembly).
Can you provide some workaround for this problem or introduce some “property” that would allow changing current scripting engine behavior (e.g. to return not loaded assemblies in some property, or to give a property that would allow assemblies that should NOT be loaded) ?
Thank you,
Krupek