18 Sep 2019

Store template documents in AppBundle

If you have a few documents that you want to use again and again as a starting point in the same Activity (i.e. use them as a template document) then you could store them in the AppBundle

This means that Design Automation would not have to download the file again and again when running a WorkItem based on the given Activity since AppBundles are cached
This way the execution of the WorkItem would be quicker and you would not have to provide the URL to the template each time you create a WorkItem for the Activity

I can think of two scenarios and their solution:
(in case of the below solutions my AppBundle is named OpenTemplateFromBundle)

1) If you always want to start with the same template document, then you could just add its path to the Activity's commandLine parameter. We already have a way to get the path of the AppBundle's folder using appbundles[] so we just have to add the relative path inside the zip to the template document

Template path in zip

commandLine parameter:

$(engine.path)\InventorCoreConsole.exe
/i $(appbundles[OpenTemplateFromBundle].path)\OpenTemplateFromBundlePlugin.bundle\Contents\template.ipt
/al $(appbundles[OpenTemplateFromBundle].path)

AppBundle code:

public void Run(Document doc)
{
  LogTrace("Run called with {0}", doc.DisplayName);
  // Retrieve parameters passed to WorkItem
  Dictionary<string, string> parameters = 
    JsonConvert.DeserializeObject<Dictionary<string, string>>(System.IO.File.ReadAllText("params.json"));

  // Do something with the opened template document
}

Parameters to start WorkItem:

{
  "inputJson": {
    "localName": "params.json",
    "url": "data:application/json,{\"height\":\"16 in\", \"width\":\"10 in\"}"
  },
  "outputFile": {
    "verb": "put",
    "localName": "outputFile.ipt",
    "url": "<signed URL>"
  }
}

2) If you use a different template depending on some incoming parameters, then one parameter could be the path of the template document (or your add-in could have all those paths inside the code). In this case, you could start by not opening any documents as part of the commandLine, but read the input.json to find the relevant path to use. We'll use the path of the add-in dll as a reference, so the "templatePath" only needs to contain the path of the template document relative to the dll's path 

commandLine parameter:

$(engine.path)\InventorCoreConsole.exe /al $(appbundles[OpenTemplateFromBundle].path)

AppBundle code:

public void Run(Document doc)
{
  // Note: doc is null since nothing is opened through the
  // command line. We're going to open the template below 
  Dictionary<string, string> parameters =
    JsonConvert.DeserializeObject<Dictionary<string, string>>(System.IO.File.ReadAllText("params.json"));

  // Get path of add-in dll
  string assemblyPath = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
  LogTrace("Assembly Path = " + assemblyPath);

  // Path of template relative to the dll's path
  string templatePath = parameters["templatePath"];

  // Open template document
  string fullPath = System.IO.Path.Combine(assemblyPath, templatePath);
  PartDocument partDoc = inventorApplication.Documents.Open(fullPath) as PartDocument;
  LogTrace("Opened template document");

  // Do something with the opened template document
}

Parameters to start WorkItem:

{
  "inputJson": {
    "localName": "params.json",
    "url": "data:application/json,{\"templatePath\": \"template.ipt\", \"height\":\"16 in\", \"width\":\"10 in\"}"
  },
  "outputFile": {
    "verb": "put",
    "localName": "outputFile.ipt",
    "url": "<signed URL>"
  }
}

The app bundle and input/output file locations are different:

app bundle folder:
  - location looks like "T:\Aces\Applications\b8...OSY.MyApp[1].package"
  - provides read-only access
  - you can find it using either of these:
    a) reference it in the commandLine with $(appbundles[MyApp].path) - see sample above
    b) get the location of the app bundle dll inside it using System.Reflection.Assembly.GetExecutingAssembly().Location and look for anything else relative to that
  - you can use multiple app bundles from an activity and they can also be resource-only (i.e. containing no app bundle code just e.g. a template document)
  - if storing e.g. a full assembly (or anything which might require saving) in the app bundle location, then the best might be to copy it over to the current directory of the work item (where you have read/write access) before using them

input/output folder:
  - location looks like "T:\Aces\Jobs\559acbcc0b4a44a3903fdfd55d2eaf2f"
  - provides read/write access
  - you can find it using System.IO.GetCurrentDirectory()
  - this is where input files are downloaded to and where design automation looks for output files to upload once the work item finished

Related Article