ADN Open CIS
Сообщество программистов Autodesk в СНГ

29/04/2020

Design Automatiion: Запуск дополнительных утилит в WorkItem

Основной задачей Design Automation API является возможность запуска различных продуктов Autodesk в облаке. Но у Вас могут быть какие-то существующие программы, которые Вы, возможно, хотите запустить в рамках Вашего рабочего процесса. Тогда для Вас хорошей новостью будет описанный в этой статье способ запуска таких программ. Конечно, есть некоторые ограничения. Во-первых, эти программы не должны требовать установки,   должно быть достаточно загрузить в облако exe-файл, возможно, какие-то файлы библиотек, дополнительные ресурсы. Во-вторых, может оказаться так, что какие-то ресурсы окажутся недоступными в виртуальной машине, в которой запускается задача Design Automation.

Для того, чтобы запустить программу, достаточно просто добавить её в архив AppBundle и добавить в командную строку Activity в нужном порядке несколько строк, как в этом примере:

Код - JavaScript: [Выделить]
  1. "commandLine": [
  2.   "$(engine.path)\\InventorCoreConsole.exe /al $(appbundles[ObjUpdater].path)",
  3.   "$(appbundles[ObjUpdater].path)\\ObjUpdaterPlugin.bundle\\Contents\\MyUtility.exe input.obj output.obj"
  4. ]

Одной из проблем, с которой я встретился, было то, что sandboxer на наших серверах добавляет дополнительные аргументы командной строки при запуске программы. Если это проблема (например, программа возвращает что-то вроде «input parameter not recognized»), то я нашёл для Вас по крайней мере два способа, как это исправить:

а) Использовать batch-файл (*.bat)

Это, наверное, самый простой способ. Единственная хитрость, это получить полный путь к запускаемой программе. Поскольку *.bat и *.exe файлы должны быть где-то рядом в папке Contents архива AppBundle, можно использовать путь к родительской папке *.bat файла:

https://stackoverflow.com/questions/2730643/how-to-execute-programs-in-the-same-directory-as-the-windows-batch-file

Содержимое MyUtility.bat:

Код - HTML: [Выделить]
  1. %~dp0MyUtility.exe input.obj output.obj

Теперь нужно поправить аргумент командной строки Activity, чтобы запускать batch файл.

Код - JavaScript: [Выделить]
  1. "commandLine": [
  2.   "$(engine.path)\\InventorCoreConsole.exe /al $(appbundles[ObjUpdater].path)",
  3.   "$(appbundles[ObjUpdater].path)\\ObjUpdaterPlugin.bundle\\Contents\\MyUtility.bat"
  4. ]

б) Запускать программу из кода AppBundle

Если Вы запускете .Net-код в AppBundle, используйте объект класса Process для запуска внешней программы из Вашего кода:

Код - C#: [Выделить]
  1. public void Run(Document doc)
  2. {
  3.   LogTrace("Run called");
  4.   string codeBase = Assembly.GetExecutingAssembly().CodeBase;
  5.   UriBuilder uri = new UriBuilder(codeBase);
  6.   string path = Uri.UnescapeDataString(uri.Path);
  7.   string dir = System.IO.Path.GetDirectoryName(path);
  8.   LogTrace("Assembly folder: " + dir);
  9.   string utilityPath = System.IO.Path.Combine(dir, "MyUtility.exe");
  10.   if (System.IO.File.Exists(utilityPath))
  11.   {
  12.     LogTrace(utilityPath + " found");
  13.     ProcessStartInfo psi = new ProcessStartInfo(
  14.       utilityPath,
  15.       "input.obj output.obj"
  16.     );
  17.     psi.RedirectStandardOutput = true;
  18.     psi.UseShellExecute = false;
  19.     Process p = Process.Start(psi);
  20.     LogTrace("Waiting for utility to finish");
  21.     p.WaitForExit();
  22.     LogTrace("Utility finished");
  23.   }
  24.   else
  25.   {
  26.     LogTrace(utilityPath + " not found");
  27.   }
  28. }

Этот способ, на самом деле обладает большим потенциалом чем просто решение проблемы автоматической подстановки дополнительных параметров в командную строку запускаемой программы. Он так же позволит

-        запускать программу нужное Вам количество раз в цикле

-        менять параметры командной строки запускаемой программы

В этом случае, в командную строку Activity добавлять запуск программы не требуется:

Код - JavaScript: [Выделить]
  1. "commandLine": [
  2.   "$(engine.path)\\InventorCoreConsole.exe /al $(appbundles[ObjUpdater].path)"
  3. ]

 

Источник: https://forge.autodesk.com/blog/run-additional-programs-inside-workitem

Автор перевода: Александр Игнатович
Опубликовано 29.04.2020