public XbimGeometryParser() { // Warn if runtime for Engine is not present, this is not necessary any more as we are net472 //XbimPrerequisitesValidator.Validate(); var conventions = new XbimArchitectureConventions(); // understands the process we run under string assemblyName = $"{conventions.ModuleName}.dll"; // + conventions.Suffix; dropping the use of a suffix try { var ass = Assembly.Load(assemblyName); var t = ass.GetType("Xbim.Geometry.XbimGeometryParser"); var obj = Activator.CreateInstance(t); if (obj == null) { throw new Exception("Failed to create Geometry Engine"); } Parser = obj as IXbimGeometryParser; if (Parser == null) { throw new Exception("Failed to cast Geometry Engine to IXbimGeometryEngine"); } } catch (Exception e) { throw new FileLoadException($"Failed to load Xbim.Geometry.Engine{conventions.Suffix}.dll", e); } }
// TODO: This approach will need revisiting should we support other CPU architectures such as ARM in future. // In order to support side-by-side deployment of both 32 bit & 64 bit versions of the native Xbim.Geometry.Engine.dll we // firstly give each architecture DLL a unique suffix (32/64), and support loading of the correct image from a sub folder under the // application bin. i.e. bin/x86/ and bin/x64/. This folder deployment strategy avoids BadImageFormatException issues with // ASP.NET (amongst others) where the runtime loads all DLLs in the bin folder at startup. // As a result we need to overide the default probing rules to locate the assembly, based whether we are 32-bit or 64-bit process. private static Assembly ProbeForAssembly(string moduleName) { Assembly assembly = Assembly.GetExecutingAssembly(); // The Xbim.Geometry.Engine.Interop assembly // code base always points to the deployed DLL, which may be different to the executing Location because of Shadow Copying in the AppDomain (e.g. ASP.NET) var codepath = new Uri(assembly.CodeBase); // Unlike Assembly.Location, CodeBase is a URI [file:\\c:\wwwroot\etc\WebApp\bin\Xbim.Geometry.Engine.Interop.dll] var appDir = Path.GetDirectoryName(codepath.LocalPath); if (appDir == null) { Logger.WarnFormat("Unable to resolve {0} because the system was not able to acquire base location of running application from {1}.", moduleName, assembly.FullName); return(null); } string libraryPath = null; if (moduleName.StartsWith(GeometryModuleName)) { // Get conventions used by this process architecture var conventions = new XbimArchitectureConventions(); // Append the relevant suffix var filename = String.Format("{0}{1}.dll", GeometryModuleName, conventions.Suffix); // Look in relevant Architecture subfolder off the main application deployment libraryPath = Path.Combine(appDir, conventions.SubFolder, filename); // Try a relative folder to CWD. if (!File.Exists(libraryPath)) { Logger.DebugFormat("Assembly not found at {0}. Attempting relative path...", libraryPath); libraryPath = Path.Combine(conventions.SubFolder, filename); } } else if (moduleName.StartsWith(XbimModulePrefix) && !moduleName.Contains("resources")) { // TODO: unclear if this has to do with Geometry Resolving. Suggest this gets moved to a dedicated handler with plugins code. // If the *32.dll or *64.dll is loaded from a // subdirectory (e.g. plugins folder), .net can // fail to resolve its dependencies so this is // to give it a helping hand var splitName = moduleName.Split(','); if (splitName.Length >= 1) { libraryPath = Path.Combine(appDir, splitName[0] + ".dll"); } } Assembly loadedAssembly = null; if (libraryPath != null) { loadedAssembly = LoadAssembly(moduleName, libraryPath); } return(loadedAssembly); }
// TODO: This approach will need revisiting should we support other CPU architectures such as ARM in future. // In order to support side-by-side deployment of both 32 bit & 64 bit versions of the native Xbim.Geometry.Engine.dll we // firstly give each architecture DLL a unique suffix (32/64), and support loading of the correct image from a sub folder under the // application bin. i.e. bin/x86/ and bin/x64/. This folder deployment strategy avoids BadImageFormatException issues with // ASP.NET (amongst others) where the runtime loads all DLLs in the bin folder at startup. // As a result we need to overide the default probing rules to locate the assembly, based whether we are 32-bit or 64-bit process. private static Assembly ProbeForAssembly(string moduleName) { Assembly assembly = Assembly.GetExecutingAssembly(); // The Xbim.Geometry.Engine.Interop assembly // code base always points to the deployed DLL, which may be different to the executing Location because of Shadow Copying in the AppDomain (e.g. ASP.NET) var codepath = new Uri(assembly.CodeBase); // Unlike Assembly.Location, CodeBase is a URI [file:\\c:\wwwroot\etc\WebApp\bin\Xbim.Geometry.Engine.Interop.dll] var appDir = Path.GetDirectoryName(codepath.LocalPath); if (appDir == null) { Logger.WarnFormat("Unable to resolve {0} because the system was not able to acquire base location of running application from {1}.", moduleName, assembly.FullName); return null; } string libraryPath = null; if (moduleName.StartsWith(GeometryModuleName)) { // Get conventions used by this process architecture var conventions = new XbimArchitectureConventions(); // Append the relevant suffix var filename = String.Format("{0}{1}.dll", GeometryModuleName, conventions.Suffix); // Look in relevant Architecture subfolder off the main application deployment libraryPath = Path.Combine(appDir, conventions.SubFolder, filename); // Try a relative folder to CWD. if (!File.Exists(libraryPath)) { Logger.DebugFormat("Assembly not found at {0}. Attempting relative path...", libraryPath); libraryPath = Path.Combine(conventions.SubFolder, filename); } } else if (moduleName.StartsWith(XbimModulePrefix) && !moduleName.Contains("resources")) { // TODO: unclear if this has to do with Geometry Resolving. Suggest this gets moved to a dedicated handler with plugins code. // If the *32.dll or *64.dll is loaded from a // subdirectory (e.g. plugins folder), .net can // fail to resolve its dependencies so this is // to give it a helping hand var splitName = moduleName.Split(','); if (splitName.Length >= 1) { libraryPath = Path.Combine(appDir, splitName[0] + ".dll"); } } Assembly loadedAssembly = null; if (libraryPath != null) { loadedAssembly = LoadAssembly(moduleName, libraryPath); } return loadedAssembly; }
public XbimGeometryEngine() { // Warn if runtime for Engine is not present XbimPrerequisitesValidator.Validate(); var conventions = new XbimArchitectureConventions(); // understands the process we run under string assemblyName = "Xbim.Geometry.Engine" + conventions.Suffix; ObjectHandle oh = Activator.CreateInstance(assemblyName, "Xbim.Geometry.XbimGeometryCreator"); _engine = oh.Unwrap() as IXbimGeometryCreator; }
public XbimGeometryEngine() { // Warn if runtime for Engine is not present XbimPrerequisitesValidator.Validate(); var conventions = new XbimArchitectureConventions(); // understands the process we run under string assemblyName = conventions.ModuleName + conventions.Suffix; try { var ass = Assembly.Load(assemblyName); var oh = Activator.CreateInstance(ass.FullName, "Xbim.Geometry.XbimGeometryCreator"); _engine = oh.Unwrap() as IXbimGeometryEngine; } catch (Exception e) { throw e; } }
public XbimGeometryEngine(ILogger <XbimGeometryEngine> logger) { // Warn if runtime for Engine is not present, this is not necessary any more as we are net472 //XbimPrerequisitesValidator.Validate(); _logger = logger ?? XbimLogging.CreateLogger <XbimGeometryEngine>(); var conventions = new XbimArchitectureConventions(); // understands the process we run under string assemblyName = $"{conventions.ModuleName}{conventions.Suffix}"; // Fixed error "simple name should be the same as resolved assembly", eirik 1/15/2021 _logger.LogDebug("Loading {assemblyName}", assemblyName); try { var ass = Assembly.Load(assemblyName); _logger.LogTrace("Loaded {fullName} from {codebase}", ass.GetName().FullName, ass.CodeBase); var t = ass.GetType("Xbim.Geometry.XbimGeometryCreator"); var obj = Activator.CreateInstance(t); _logger.LogTrace("Created Instance of {fullName}", obj.GetType().FullName); if (obj == null) { throw new Exception("Failed to create Geometry Engine"); } _engine = obj as IXbimGeometryEngine; if (_engine == null) { throw new Exception("Failed to cast Geometry Engine to IXbimGeometryEngine"); } _logger.LogDebug("XbimGeometryEngine constructed successfully"); } catch (Exception e) { _logger.LogError(0, e, "Failed to construct XbimGeometryEngine"); throw new FileLoadException($"Failed to load Xbim.Geometry.Engine.dll{conventions.Suffix}", e); } }
// TODO: This approach will need revisiting should we support other CPU architectures such as ARM in future. // In order to support side-by-side deployment of both 32 bit & 64 bit versions of the native Xbim.Geometry.Engine.dll we // firstly give each architecture DLL a unique suffix (32/64), and support loading of the correct image from a sub folder under the // application bin. i.e. bin/x86/ and bin/x64/. This folder deployment strategy avoids BadImageFormatException issues with // ASP.NET (amongst others) where the runtime loads all DLLs in the bin folder at startup. // As a result we need to overide the default probing rules to locate the assembly, based whether we are 32-bit or 64-bit process. private static Assembly ProbeForAssembly(string moduleName) { var appDir = Environment.GetEnvironmentVariable("GeometryEngineLocation"); if (string.IsNullOrWhiteSpace(appDir) || !Directory.Exists(appDir)) { _logger.LogDebug("Getting probing path from executing assembly"); Assembly assembly = Assembly.GetExecutingAssembly(); // The Xbim.Geometry.Engine.Interop assembly // code base always points to the deployed DLL, which may be different to the executing Location because of Shadow Copying in the AppDomain (e.g. ASP.NET) var codepath = new Uri(assembly.CodeBase); // Unlike Assembly.Location, CodeBase is a URI [file:\\c:\wwwroot\etc\WebApp\bin\Xbim.Geometry.Engine.Interop.dll] appDir = Path.GetDirectoryName(codepath.LocalPath); } _logger.LogDebug("Probing path {appDir}", appDir); if (appDir == null) { return(null); } string libraryPath = null; if (moduleName.StartsWith(GeometryModuleName)) { // Get conventions used by this process architecture var conventions = new XbimArchitectureConventions(); // Append the relevant suffix // var filename = String.Format("{0}{1}.dll", conventions.ModuleName, conventions.Suffix); //dropping the use of a suffix var filename = $"{conventions.ModuleName}{conventions.Suffix}.dll"; // Look in relevant Architecture subfolder off the main application deployment libraryPath = Path.Combine(appDir, filename); _logger.LogDebug("Probing for GeometryEngine in {path}", libraryPath); // Try a relative folder to CWD. if (!File.Exists(libraryPath)) { _logger.LogDebug("Not found - falling back to search for {filename} instead", filename); libraryPath = filename; } } else if (moduleName.StartsWith(XbimModulePrefix) && !moduleName.Contains("resources")) { // TODO: unclear if this has to do with Geometry Resolving. Suggest this gets moved to a dedicated handler with plugins code. // If the *32.dll or *64.dll is loaded from a // subdirectory (e.g. plugins folder), .net can // fail to resolve its dependencies so this is // to give it a helping hand var splitName = moduleName.Split(','); if (splitName.Length >= 1) { libraryPath = Path.Combine(appDir, splitName[0] + ".dll"); } } Assembly loadedAssembly = null; if (libraryPath != null) { loadedAssembly = LoadAssembly(moduleName, libraryPath); } return(loadedAssembly); }