Skip to content

WPF control library's resource assembly not found at runtime despite being present in output directory (worked before system reinstall) #795

@yangf85

Description

@yangf85

Description

Environment:

  • ExcelDNA Version: [1.9.0beta]
  • .NET Framework: [net8-windows;net48]
  • Excel Version: [2016]
  • Visual Studio: [2022]
  • Windows Version: [win10]

Problem:
I'm developing an ExcelDNA add-in that references a WPF control library via NuGet. This control library has a dependency on a style/theme resource assembly (Cyclone.Wpf.Themes).

Critical Information: This add-in was working perfectly before I reinstalled Windows. After the system reinstall, with the same code and project configuration, the add-in now throws a FileNotFoundException for the resource assembly.

Important: The Cyclone.Wpf.Themes.dll file IS present in the bin\Debug (or bin\Release) directory after building, sitting right next to the main add-in DLL and the .xll file. However, when the ExcelDNA add-in launches a WPF window at runtime, it throws a FileNotFoundException for this assembly.

Error Message:

System.Windows.Markup.XamlParseException
  HResult=0x80131501
  Message="设置属性"System.Windows.ResourceDictionary.Source"时引发了异常。",行号为"3",行位置为"10"。
  Source=PresentationFramework
  StackTrace:
   在 System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
   在 System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   在 System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
   在 System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   在 System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
   在 Cyclone.ExcelToolkit.Views.OrderDataFillView.InitializeComponent() 在 E:\Code\Cyclone\ExcelToolkit\Cyclone.ExcelToolkit\Views\Production\OrderDataFillView.xaml 中: 第 1 行

内部异常 1:
FileNotFoundException: Could not load file or assembly 'Cyclone.Wpf.Themes, Culture=neutral, PublicKeyToken=null'. 系统找不到指定的文件。

Project Structure:

ExcelDNA Add-in Project
├── References WPF Control Library (NuGet)
    └── WPF Control Library references Cyclone.Wpf.Themes (style/resource assembly)

Output Directory (bin\Debug):
├── MyAddIn.dll
├── MyAddIn.xll
├── MyAddIn-packed.xll
├── WpfControlLibrary.dll
├── Cyclone.Wpf.Themes.dll  ← THIS FILE EXISTS HERE
└── Other dependencies...

Steps to Reproduce:

  1. Create an ExcelDNA add-in project using the latest NuGet package
  2. Add a reference to a WPF control library that depends on a separate resource assembly
  3. Build the project - verify that all DLLs including Cyclone.Wpf.Themes.dll are in the output directory
  4. Create a WPF window that uses controls from the library
  5. Launch the window from the Excel add-in
  6. The FileNotFoundException occurs when the window tries to load resources, even though the DLL is physically present in the same directory

Temporary Workaround Found:
I've found that manually handling the AssemblyResolve event works:

public void AutoOpen()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        var assemblyName = new AssemblyName(args.Name).Name;
        if (assemblyName == "Cyclone.Wpf.Themes")
        {
            var xllPath = ExcelDnaUtil.XllPath;
            var xllDir = Path.GetDirectoryName(xllPath);
            var dllPath = Path.Combine(xllDir, "Cyclone.Wpf.Themes.dll");
            
            if (File.Exists(dllPath))
            {
                return Assembly.LoadFrom(dllPath);
            }
        }
        return null;
    };
}

However, this is not an elegant solution and shouldn't be necessary. The fact that this workaround is required suggests that the assembly search path is not properly configured when running inside Excel after the system reinstall.

What Changed:

  • Before system reinstall: The add-in worked perfectly with the exact same code and project structure
  • After system reinstall: The FileNotFoundException occurs
  • No code changes were made between the working and non-working states
  • All Visual Studio, .NET Framework, and Excel versions were reinstalled to the same versions as before

Additional Information:

  • The Cyclone.Wpf.Themes.dll IS present in the bin\Debug directory - this is not a build/copy issue
  • The same WPF window works correctly in a standalone WPF application with the same DLL structure
  • The issue only occurs when running as an ExcelDNA add-in within Excel process
  • The resource dictionary is referenced in XAML like: <ResourceDictionary Source="/Cyclone.Wpf.Themes;component/Themes/Generic.xaml"/>
  • Using Process Monitor shows Excel is not even attempting to load the DLL from the add-in directory
  • The AssemblyResolve workaround proves the DLL can be loaded, but Excel/WPF is not looking in the XLL directory by default

Expected Behavior:
Since all required DLLs are present in the output directory, and the add-in worked before the system reinstall, the WPF window should be able to load its resource assemblies when launched from the ExcelDNA add-in without requiring manual assembly resolution.

Core Questions:

  1. Why doesn't Excel/WPF search for assemblies in the XLL directory by default after a system reinstall?
  2. What system-level configuration or dependency could have changed after a Windows reinstall that would affect assembly loading in ExcelDNA but not in standalone applications?
  3. Is there a proper way to configure ExcelDNA or Excel to include the XLL directory in the assembly search path without using AssemblyResolve?
  4. Could this be related to how Excel's working directory or AppDomain base directory is set up in a fresh Windows installation?
  5. Is there a recommended best practice for handling WPF resource assemblies in ExcelDNA add-ins that doesn't require manual assembly resolution?
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions