3

I have a C# WPF class library which uses (references) SharpVectors. This class library exports a function to COM which creates & shows the WPF window. The COM client is VB6 although I'm not sure that matters.

When it runs I get "System.Windows.Markup.XamlParseException" on the first XAML line to access a SharpVectors object.

I think that exception is somewhat of a catch-all; but the InnerException contains:

Message:

Could not load file or assembly 'SharpVectors.Converters.Wpf, PublicKeyToken=b532964b8548be77' or one of its dependencies. The system cannot find the file specified.

However SharpVectors.Converters.Wpf.dll has been copied to the bin/Debug folder alongside the DLL from my project. As well as other SharpVectors dependencies.

I've pasted more exception details below.

When I've run this same test assembly from a C# WPF application, no problem. So it seems like somehow the C# runtime is losing track of the assembly location when called via COM interop. Is there some way to get it back on track?

InnerException Stack:

   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.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.Reflection.Assembly.Load(AssemblyName assemblyRef)
   at System.Windows.Baml2006.Baml2006SchemaContext.ResolveAssembly(BamlAssembly bamlAssembly)
   at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlTypeToType(BamlType bamlType)
   at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlType(BamlType bamlType, Int16 typeId)
   at System.Windows.Baml2006.Baml2006SchemaContext.GetXamlType(Int16 typeId)
   at System.Windows.Baml2006.Baml2006Reader.Process_ElementStart()
   at System.Windows.Baml2006.Baml2006Reader.Process_OneBamlRecord()
   at System.Windows.Baml2006.Baml2006Reader.Process_BamlRecords()
   at System.Windows.Baml2006.Baml2006Reader.Read()
   at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)

InnerException Fusion log:

=== Pre-bind state information ===
LOG: DisplayName = SharpVectors.Converters.Wpf, PublicKeyToken=b532964b8548be77
 (Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: SharpVectors.Converters.Wpf, PublicKeyToken=b532964b8548be77 | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/VB98/
LOG: Initial PrivatePath = NULL
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.

The code below is the most minimal example I can make up which reproduces the issue. The error occurs on the <svgc:SvgControl .../> line.

XAML code:

<Window x:Class="TestSubassembly.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        Title="TEST" Height="250" Width="256"
        >

            <svgc:SvgControl Source="sample.svg"/>
</Window>

C# code-behind:

    public MainWindow()
    {
        InitializeComponent();
    }

C# COM-visible class:

[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("...")]
[ComVisible(true)]
public class TestLoader
{
    public void Load()
    {
        var w = new TestSubassembly.MainWindow();
        w.Show();
    }
}

VB6 code:

Private Sub Form_Load()
    Dim l As New TestLoader
    l.Load
End Sub

Edit: I can also reproduce this with classes from libraries other than SharpVectors. For instance, Xceed toolkit controls. So this really seems to be a general problem with how assemblies are resolved or loaded in the way my app is structured.

Also, I tried a variant of this where the SharpVector libraries were added directly to my solution & compiled (not using the Nuget DLLs) - this had no effect; same problem.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
  • I understand that you get this error when adding the particular nuget to WPF Class library only, is that right ? – Clint Feb 07 '20 at 18:24
  • @Clint it is added to my class library, that's correct. See my bottom edit though, it will happen with other nuget packages also. – StayOnTarget Feb 07 '20 at 18:25
  • right, you have to add the reference to this dll/nuget to your main project – Clint Feb 07 '20 at 18:27
  • But the "main project" is unmanaged - its not a .NET executable. I can't reference the other DLLs there. – StayOnTarget Feb 07 '20 at 18:28
  • This is what I tried, created a WPF Class Lib which references Sharp Vector libs to display a svg image and I added this DLL to my WPF project where I'm Invoking the MainWindow.Show() of my dll. and it works fine. Did I miss something ? – Clint Feb 07 '20 at 19:01
  • @Clint that seems similar; your main project is a .NET executable but mine is an unmanaged executable. That seems like the main difference. Thanks for trying to reproduce it. – StayOnTarget Feb 07 '20 at 19:12
  • Hmm I believe this is the flow then MainProject(Unmanaged) -> WPF App -> WPF Lib – Clint Feb 07 '20 at 19:29
  • In my simplified test case the "WPF App" node does not exist; but this is actually very similar to my real app. – StayOnTarget Feb 07 '20 at 19:37

0 Answers0