15 Jul 2020

Resolving referenced Inventor files

Strictly speaking, this is not a Design Automation specific topic, but it does have some aspects relevant to it.

Inventor mainly relies on paths set in the active Project to resolve Inventor files referenced by assemblies.
Having an active Project seems to be even more important when using the Inventor API, as opposed to doing things through the User Interface of Inventor.

By default, when running a WorkItem the Default Project will be used (Default.ipj), whose settings cannot be changed, and that can be a problem depending on what you are doing - mentioned here too.

a) There is a new commandLine option for Activity's introduced recently, the "/p" option, which will create a Project with Workspace path set to the WorkItem's working folder (where the input files are placed as well) and activate it. Here is an example for such commandLine:

"$(engine.path)\\InventorCoreConsole.exe /al $(appbundles[MyAppBundle].path) /p"

If all the files you are using are in the Working Folder or its sub folders, then that might be enough.

However, you might be working with files stored in the AppBundle
In that case, you could either update the WorkspacePath of the ActiveProject to the AppBundle's path or add it to WorkgroupPaths:

inventorApplication.DesignProjectManager.ActiveDesignProject.WorkspacePath = appBundleContentsFolder;
// or
inventorApplication.DesignProjectManager.ActiveDesignProject.WorkgroupPaths.Add("Contents", appBundleContentsFolder);

b) You could also use your own Project - perhaps one that was created when you used "Pack and Go" for your assembly. You just have to find that project file (*.ipj), load it, and activate it:

DesignProject dp = inventorApplication.DesignProjectManager.DesignProjects.AddExisting(pathToMyProject);

Make sure you're not opening any document (through the API or the commandLine of the Activity using /i option) before loading the Project or modifying its paths.

c) There is another option though, in case you prefer that, which is handling the OnFileResolution event to help Inventor find the files:

// Make sure you keep a reference to events objects otherwise the events won't fire
FileAccessEvents fae = inventorApplication.FileAccessEvents;
fae.OnFileResolution += Fae_OnFileResolution;

// etc

private void Fae_OnFileResolution(
  string RelativeFileName, 
  string LibraryName, 
  ref byte[] CustomLogicalName, 
  EventTimingEnum BeforeOrAfter, 
  NameValueMap Context, 
  out string FullFileName, 
  out HandlingCodeEnum HandlingCode)
  // It's best practice to first say we didn't handle the event 
  // and then change it later on if needed  
  HandlingCode = HandlingCodeEnum.kEventNotHandled;

  // Let's say all my parts will be in this specific folder
  string partsFolder = System.IO.Path.Combine(g_bundlePath, "SampleBundlePlugin.bundle", "Contents", "MyParts");
  // Get the file name without the path          
  string fileName = System.IO.Path.GetFileName(RelativeFileName);

  // Combine it with our folder
  FullFileName = System.IO.Path.Combine(partsFolder, fileName);  
  if (System.IO.File.Exists(FullFileName))
    HandlingCode = HandlingCodeEnum.kEventHandled;                

In this case, make sure that "Embed Interop Types" of the AppBundle project's reference to Autodesk.Inventor.Interop.dll is set to "False" - as mentioned here too.
Without taking care of that I was not able to not handle the event, i.e. set the HandlingCode to HandlingCodeEnum.kEventNotHandled, when I could not find a file. And that caused problems.

Apart from setting "Embed Interop Types" to "False", you should also set "Copy Local" to "True" so that the specific Inventor interop dll your project is using will be available in the AppBundle.

Embed Interop Types False

Otherwise, you'll likely run into this error when using your AppBundle on Design Automation:

"Could not load file or assembly 'Autodesk.Inventor.Interop, Version=, Culture=neutral, PublicKeyToken=d84147f8b4276564' or one of its dependencies. The system cannot find the file specified."

Also, just ran into this diagram that is in the Assembly Advanced presentation of the Inventor API training material. This could also be useful to understand where Inventor is looking for files and in what order:

Inventor File Resolution

Related Article