Wednesday 3 February 2010

WPF + Geospatial Platform API = A recipe for failure

If you use WPF in your AutoCAD Map applications and you are using the Geospatial Platform API you may encounter something like this when designing any WPF content:



The type initializer for '<Module>' threw an exception.
at System.Reflection.CustomAttribute._CreateCaObject(Void* pModule, Void* pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.CreateCaObject(Module module, RuntimeMethodHandle ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
at System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(Assembly assembly, RuntimeType caType)
at System.Reflection.Assembly.GetCustomAttributes(Boolean inherit)
at MS.Internal.ReferenceAssemblyUtils.SafeGetCustomAttributes(Assembly assembly, Type filter, Boolean inherit)
at MS.Internal.Xaml.ReflectionProjectNode.BuildNamespaces()
at MS.Internal.Xaml.ReflectionProjectNode.Find(Identifier namespaceUri)
at MS.Internal.Xaml.PrefixScope.FindType(XamlName name)
at MS.Internal.Xaml.XmlElement.FindElementType(PrefixScope parentScope, IParseContext context)
at MS.Internal.DocumentTrees.Markup.XamlSourceDocument.get_RootType()
at Microsoft.Windows.Design.Documents.Trees.MarkupDocumentTreeManager.get_RootType()
at Microsoft.Windows.Design.Documents.MarkupDocumentManager.CalculateLoadErrorState()
at Microsoft.Windows.Design.Documents.MarkupDocumentManager.get_LoadState()
at MS.Internal.Host.PersistenceSubsystem.Load()
at MS.Internal.Host.Designer.Load()
at MS.Internal.Designer.VSDesigner.Load()
at MS.Internal.Designer.VSIsolatedDesigner.VSIsolatedView.Load()
at MS.Internal.Designer.VSIsolatedDesigner.VSIsolatedDesignerFactory.Load(IsolatedView view)
at MS.Internal.Host.Isolation.IsolatedDesigner.BootstrapProxy.LoadDesigner(IsolatedDesignerFactory factory, IsolatedView view)
at MS.Internal.Host.Isolation.IsolatedDesigner.BootstrapProxy.LoadDesigner(IsolatedDesignerFactory factory, IsolatedView view)
at MS.Internal.Host.Isolation.IsolatedDesigner.Load()
at MS.Internal.Designer.DesignerPane.LoadDesignerView()


A nested exception occurred after the primary exception that caused the C++ module to fail to load.

at <CrtImplementationDetails>.ThrowNestedModuleLoadException(Exception innerException, Exception nestedException)
at <CrtImplementationDetails>.ThrowNestedModuleLoadException(Exception , Exception )
at <CrtImplementationDetails>.LanguageSupport.Cleanup(LanguageSupport* , Exception innerException)
at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )
at .cctor()


Type constructor threw an exception.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr function, Void* cookie)
at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr , Void* )
at <CrtImplementationDetails>.LanguageSupport.InitializeDefaultAppDomain(LanguageSupport* )
at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* )
at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )

Though you can still build and run the project, the WPF designer is completely hosed, all intellisense is lost and as a result, the WPF designer becomes a bloated version of notepad.

The reason that happens is because the Autodesk.Map.Platform.dll is actually just a thin managed wrapper to the unmanaged AcMap* dlls in your AutoCAD Map installation, so the WPF designer is actually trying to locate these dlls from either:
  • The project's output directory
  • Or, some special working directory that's defined by Visual Studio (where this is, I have no idea)
After 5 hours of sleuthing around, I have found an acceptable workaround.

Simply put the AutoCAD Map installation directory into your PATH environment variable and restart Visual Studio. The WPF designer will correctly locate the AcMap* dlls and you'll regain full designer functionality.

This little tip will no doubt be useful to someone out there. I lost 5 work hours so you don't have to :-)

1 comment:

Anonymous said...

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup\Windows Presentation Foundation]
@="WPF v3.0.6920.1453"
"Version"="3.0.6920.1453"
"WPFReferenceAssembliesPathx86"="C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\v3.0\\"
"WPFCommonAssembliesPathx86"="C:\\Windows\\System32\\"
"InstallRoot"="C:\\Windows\\Microsoft.NET\\Framework\\v3.0\\WPF\\"
"InstallSuccess"=dword:00000001
"ProductVersion"="3.0.6920.1453"
"WPFNonReferenceAssembliesPathx86"="C:\\Windows\\Microsoft.NET\\Framework\\v3.0\\WPF\\"

Check this key in registry. If missing insert it at the location specified and you are done!

Regards,
Umesh