我正在为另一个应用程序Autodesk Revit开发一个加载项,它是一个独立的DLL类库。我正在尝试在我的一个WPF窗口中使用Wpf Tool Kit Property grid。属性网格在Visual Studio中显示正常,而intellisense也可以。但是当我尝试使用加载项加载启动Revit时,我得到以下异常。
System.Windows.Markup.XamlParseException occurred
HResult=-2146233087
Message=Could not load file or assembly 'Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4' or one of its dependencies. The system cannot find the file specified.
Source=PresentationFramework
LineNumber=133
LinePosition=27
StackTrace:
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
InnerException: System.IO.FileNotFoundException
HResult=-2147024894
Message=Could not load file or assembly 'Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4' or one of its dependencies. The system cannot find the file specified.
Source=mscorlib
FileName=Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4
FusionLog==== Pre-bind state information ===
LOG: User = GLOBAL\eric.anastas
LOG: DisplayName = Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4 | 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/Autodesk/Revit 2014/
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: Using application configuration file: C:\Program Files\Autodesk\Revit 2014\Revit.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\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: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.EXE.
StackTrace:
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:
通常,当我想从Revit插件引用第三方程序集时,我只需确保将第三方DLL复制到与插件DLL相同的位置。我检查了Xceed.Wpf.Toolkit.dll
被复制到包含我的插件DLL的目录。
我从错误中的日志消息中注意到它正在Revit程序目录中查找DLL。将Xceed.Wpf.Toolkit.dll
复制到此目录后,我不再收到错误。
但是,我有现有的插件部署工具,这些工具依赖于插件文件在他们自己的隔离文件夹中。
那么,有没有人知道如何让插件找到WPF Toolkit库?
答案 0 :(得分:15)
所以,我从2014年开始为我的这个问题找到了一个新的更好的解决方案。
今天我遇到了同样的问题,从程序集加载WPF控件会抛出XamlParseException,除非这次是我创建的WPF控件库程序集。
我尝试将DLL移动到与EXE相同的文件夹中,并且像以前一样解决了这个问题。
经过一番搜索,我在telerik.com论坛上发现了这个问题: http://www.telerik.com/forums/xamlparseexception-could-not-load-file-or-assembly
事实证明,如果您只是通过添加x:Name
属性为控件命名,这将在代码隐藏中添加对控件的引用,并且由于某种原因解决了加载程序集的问题。
<!--This causes a XamlParseException -->
<mylib:MyCustomControl />
<!-- This works -->
<mylib:MyCustomControl x:Name="foobar"/>
答案 1 :(得分:9)
我是这种方法的粉丝。 您可以在AppDomain上为AssemblyResolve事件注册一个事件,该事件在无法加载程序集时捕获。
看起来像这样:
// using System.Reflection and System.IO
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args )
{
if (args.Name.ToUpper().StartsWith("XCEED.WPF"))
{
string asmLocation = Assembly.GetExecutingAssembly().Location;
string asmName = args.Name.Substring(0, args.Name.IndexOf(','));
string filename = Path.Combine( asmLocation, asmName );
if (File.Exists(filename)) return Assembly.LoadFrom(filename);
}
}
你可以让它比这更完整,但你明白了......
答案 2 :(得分:7)
我知道这是一个非常古老的问题,但我不久前碰巧碰到了这个确切的错误。如果您的visual studio应用程序使用两个项目或引用另一个项目的项目,我会检查以确保BOTH项目安装了扩展工具包。
右键单击两个项目,然后单击,&#34;管理NuGet包&#34;然后在对话框的左侧浏览&#34;已安装的软件包&#34;。如果您在两个项目中都没有看到扩展工具包,那么您可以使用管理器在线搜索并为您安装它们。
我的问题是我只在一个项目上安装了扩展工具包,而不是两者都安装。
希望将来可以帮助某人。
答案 3 :(得分:7)
虽然这可能已经解决,但常见的原因是未能将Xceed.Wpf.Toolkit dll添加到入口点项目中。您可能已将其添加到您的一个类库项目中并设置其#34;复制本地&#34;属性为true。此dll的引用也必须添加到您的主项目中,其中包含您的App.xaml.cs及其&#34; Copy Local&#34;属性设置为true。
我很惊讶Visual Studio 2013不会自动处理此问题。
答案 4 :(得分:1)
虽然我个人认为你应该按照接受的答案(@Matt)的说明进行操作,但我想提一下,将dll复制到Autodesk Revit安装中的“Program”文件夹可能也会有所帮助。 。如果我没记错的话,他们还建议你将你的插件部署到这个文件夹的子文件夹中,以确保它正常工作。我怀疑,那是因为你所拥有的效果。
答案 5 :(得分:0)
在System.Reflection
命名空间中,有Assembly
类。这可用于将新程序集加载到当前AppDomain中。
Assembly.LoadFrom("FileLocation");
虽然这仍然很烦人,但我认为这可能是让它加载不在主目录中的库的唯一方法。
答案 6 :(得分:0)
确保你&#34;取消阻止&#34; Xceed组件。右键单击该文件并选择属性然后&#34;取消阻止&#34;。 VS将编译代码而没有任何错误,但是当你去运行时,Windows将不会加载程序集。我甚至被合并成一个集会。
答案 7 :(得分:0)
从XAML加载控件时,加载Xceed.Wpf.Toolkit.dll
的调用程序集为PresentationFramework.dll
。因此,在这种情况下,CLR不会查看你的addin文件夹(当你从插件的主程序集加载另一个类时它正在做什么,因为它会查看调用程序集的文件夹)。
所以你可以找到,在代码隐藏中添加对控件的引用,或者你可以使用AppDomain.CurrentDomain.AssemblyResolve
强制CLR查看你的addin文件夹。
将dll放在Revit安装文件夹中可以正常工作,但在我看来这是一个不好的做法,因为它可能会被其他插件安装覆盖,后果难以衡量。
答案 8 :(得分:0)
我见过人们在Visual Studio Extensions中使用这种解决方法。但是,VS使用“ ProvideCodeBaseAttribute”提供了更好的解决方案:
https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.shell.providecodebaseattribute