July 15, 2020

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);
dp.Activate();

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.

Related Posts