Projektdateien hinzufügen.

This commit is contained in:
Max Richter
2025-06-11 15:01:17 +02:00
parent d4065f4938
commit 5a9085b0be
24 changed files with 1207 additions and 0 deletions

37
MachinePlannerExport.sln Normal file
View File

@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36203.30 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interaction", "MachinePlannerExport\Interaction\Interaction.csproj", "{F885727B-CE25-493C-AA28-046D0166DC4F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugPluginLocally", "MachinePlannerExport\DebugPluginLocally\DebugPluginLocally.csproj", "{3978D155-2657-4BA1-96E2-852C35E11E35}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MachinePlannerExportPlugin", "MachinePlannerExport\MachinePlannerExportPlugin\MachinePlannerExportPlugin.csproj", "{A4FE3963-6962-427C-AB50-E1F156A4E1C9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F885727B-CE25-493C-AA28-046D0166DC4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F885727B-CE25-493C-AA28-046D0166DC4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F885727B-CE25-493C-AA28-046D0166DC4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F885727B-CE25-493C-AA28-046D0166DC4F}.Release|Any CPU.Build.0 = Release|Any CPU
{3978D155-2657-4BA1-96E2-852C35E11E35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3978D155-2657-4BA1-96E2-852C35E11E35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3978D155-2657-4BA1-96E2-852C35E11E35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3978D155-2657-4BA1-96E2-852C35E11E35}.Release|Any CPU.Build.0 = Release|Any CPU
{A4FE3963-6962-427C-AB50-E1F156A4E1C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4FE3963-6962-427C-AB50-E1F156A4E1C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4FE3963-6962-427C-AB50-E1F156A4E1C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4FE3963-6962-427C-AB50-E1F156A4E1C9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {82BBE41D-AEC1-4A75-9935-EC7F612F63A1}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
</startup>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="consoleListener" type="System.Diagnostics.ConsoleTraceListener"/>
</listeners>
</trace>
</system.diagnostics>
</configuration>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3978D155-2657-4BA1-96E2-852C35E11E35}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DebugPluginLocally</RootNamespace>
<AssemblyName>DebugPluginLocally</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<MultipleProjects>true</MultipleProjects>
<PackagePath>..\..\packages</PackagePath>
<PackagePath Condition="Exists('..\packages')">..\packages</PackagePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autodesk.Inventor.Interop, Version=23.0.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>$(PackagePath)\autodesk\autodesk.inventor.interop.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="InventorConnector.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="inputFiles\box.ipt" />
<None Include="inputFiles\params.json" />
</ItemGroup>
<Choose>
<When Condition="$(MultipleProjects) == 'true'">
<ItemGroup>
<ProjectReference Include="..\MachinePlannerExportPlugin\MachinePlannerExportPlugin.csproj">
<Project>{f1c9d7e2-53a8-4e4e-af9e-931ca891715d}</Project>
<Name>MachinePlannerExportPlugin</Name>
</ProjectReference>
<!-- other ProjectReference elements -->
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<!-- other ProjectReference elements -->
</ItemGroup>
</Otherwise>
</Choose>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,95 @@
using System;
using System.Runtime.InteropServices;
using Inventor;
namespace DebugPluginLocally
{
internal class InventorConnector : IDisposable
{
Application _Instance;
bool _CreatedByUs;
const string PROG_ID = "Inventor.Application";
public InventorConnector()
{
}
public InventorServer GetInventorServer()
{
Connect();
_Instance.SilentOperation = true;
return _Instance as InventorServer;
}
private void Connect()
{
if (_Instance == null)
{
_Instance = TryConnectToRunningInstance();
if (_Instance == null)
{
_Instance = TryCreateInstance();
_CreatedByUs = _Instance != null;
}
if (_Instance == null)
throw new ApplicationException("Could not connect to Inventor.");
}
}
private static Application TryCreateInstance()
{
Console.WriteLine("Trying to create instance of Inventor...");
Application app = null;
try
{
Type type = Type.GetTypeFromProgID(PROG_ID);
app = Activator.CreateInstance(type) as Application;
Console.WriteLine($"Connected to Inventor {app.SoftwareVersion.DisplayName}");
// show Inventor UI
app.Visible = true;
}
catch (Exception e)
{
Console.WriteLine($"No running Inventor instance... ({e.Message})");
}
return app;
}
private static Application TryConnectToRunningInstance()
{
Console.WriteLine("Trying to connect to Inventor...");
Application app = null;
try
{
app = Marshal.GetActiveObject(PROG_ID) as Application;
Console.WriteLine($"Connected to Inventor {app.SoftwareVersion.DisplayName}");
}
catch /*(Exception e)*/
{
//Console.WriteLine($"Could not connect to running Inventor Instance... ({e.Message})");
}
return app;
}
public void Dispose()
{
if (_Instance != null)
{
Console.WriteLine("Closing all documents...");
_Instance.Documents.CloseAll(UnreferencedOnly: false);
if (_CreatedByUs)
{
// Uncomment to close the Inventor instance
//_Instance.Quit();
}
Console.WriteLine("Detaching from Inventor...");
Marshal.ReleaseComObject(_Instance);
_Instance = null;
}
}
}
}

View File

@ -0,0 +1,95 @@
using System;
using System.IO;
using Inventor;
namespace DebugPluginLocally
{
internal class Program
{
static void Main(string[] args)
{
using (var inv = new InventorConnector())
{
InventorServer server = inv.GetInventorServer();
try
{
Console.WriteLine("Running locally...");
// run the plugin
DebugSamplePlugin(server);
}
catch (Exception e)
{
string message = $"Exception: {e.Message}";
if (e.InnerException != null)
message += $"{System.Environment.NewLine} Inner exception: {e.InnerException.Message}";
Console.WriteLine(message);
}
finally
{
if (System.Diagnostics.Debugger.IsAttached)
{
Console.WriteLine("Press any key to exit. All documents will be closed.");
Console.ReadKey();
}
}
}
}
/// <summary>
/// Opens box.ipt and runs SamplePlugin
/// </summary>
/// <param name="app"></param>
private static void DebugSamplePlugin(InventorServer app)
{
// get project directory
string projectdir = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
// get box.ipt absolute path
string boxPath = System.IO.Path.Combine(projectdir, @"inputFiles\", "box.ipt");
string boxPathCopy = System.IO.Path.Combine(projectdir, @"inputFiles\", "boxcopy.ipt");
try
{
// delete an existing file
System.IO.File.Delete(boxPathCopy);
}
catch (IOException)
{
Console.WriteLine("The specified file is in use. It might be open by Inventor");
return;
}
// create a copy
System.IO.File.Copy(boxPath, boxPathCopy);
// open box.ipt by Inventor
Document doc = app.Documents.Open(boxPathCopy);
// get params.json absolute path
string paramsPath = System.IO.Path.Combine(projectdir, @"inputFiles\", "params.json");
// create a name value map
Inventor.NameValueMap map = app.TransientObjects.CreateNameValueMap();
// add parameters into the map, do not change "_1". You may add more parameters "_2", "_3"...
map.Add("_1", paramsPath);
// add extra parameters to showcase newly supported parsing and new helper class NameValueMapHelper
map.Add("intIndex", "1");
map.Add("stringIndex", "test");
map.Add("stringCollectionIndex", "str1, str2, str3");
map.Add("intCollectionIndex", "34, 256, 9999, 500, 43");
// create an instance of MachinePlannerExportPlugin
MachinePlannerExportPlugin.SampleAutomation plugin = new MachinePlannerExportPlugin.SampleAutomation(app);
// run the plugin
plugin.RunWithArguments(doc, map);
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DebugPluginLocally")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DebugPluginLocally")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3978d155-2657-4ba1-96e2-852c35e11e35")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1 @@
{"length":"20","width":"10"}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autodesk.Forge.DesignAutomation" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,118 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Autodesk.Forge.Core;
using Microsoft.Extensions.Configuration;
namespace Interaction
{
internal class Program
{
private struct Command
{
public string Description;
public Func<Publisher, Task> Action;
}
private static readonly Command[] commands = new Command[]
{
new Command { Description = "Post app bundle", Action = (publisher) => publisher.PostAppBundleAsync() },
new Command { Description = "Post activity", Action = (publisher) => publisher.PublishActivityAsync() },
new Command { Description = "Run work item", Action = (publisher) => publisher.RunWorkItemAsync() },
new Command { Description = "List available engines", Action = (publisher) => publisher.ListEnginesAsync() },
new Command { Description = "Clean existing app bundle and activity", Action = (publisher) => publisher.CleanExistingAppActivityAsync() },
};
static async Task Main(string[] args)
{
// TODO: ensure you've set credentials in `appsettings.json`
bool useCommandLine = (args.Length == 1);
try
{
Publisher publisher = CreatePublisher();
if (useCommandLine)
{
await RunCommand(publisher, args[0]);
}
else
{
await RunLoop(publisher);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
if (useCommandLine || Debugger.IsAttached)
{
Console.WriteLine();
Console.WriteLine("Press any key to close console...");
Console.ReadKey();
}
}
private static async Task RunLoop(Publisher publisher)
{
PrintHelp();
while (true)
{
Console.Write("> ");
// wait for pressed key
ConsoleKeyInfo key = Console.ReadKey();
if (key.Key == ConsoleKey.Q) break;
Console.WriteLine();
if (key.Key == ConsoleKey.H) { PrintHelp(); continue; }
if (key.Key == ConsoleKey.C) { Console.Clear(); continue; }
await RunCommand(publisher, key.KeyChar.ToString());
}
}
private static async Task RunCommand(Publisher publisher, string commandIndex)
{
// try to convert the key to index of available actions
if (int.TryParse(commandIndex, out var index) &&
(index >= 0 && index < commands.Length))
{
Command command = commands[index];
Console.WriteLine($"Running '{command.Description}'");
await command.Action(publisher);
}
else
{
Console.WriteLine("Unknown command");
}
}
private static void PrintHelp()
{
Console.WriteLine("Design Automation interaction console");
Console.WriteLine("Available actions:");
for (int i = 0; i < commands.Length; i++)
{
Console.WriteLine($" {i} - {commands[i].Description}");
}
Console.WriteLine(" H - Help");
Console.WriteLine(" C - Clear console");
Console.WriteLine(" Q - Quit");
}
private static Publisher CreatePublisher()
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false)
.AddEnvironmentVariables()
.AddForgeAlternativeEnvironmentVariables()
.Build();
return new Publisher(configuration);
}
}
}

View File

@ -0,0 +1,121 @@
using System.Collections.Generic;
using Autodesk.Forge.DesignAutomation.Model;
namespace Interaction
{
/// <summary>
/// Customizable part of Publisher class.
/// </summary>
internal partial class Publisher
{
/// <summary>
/// Constants.
/// </summary>
private static class Constants
{
// Constants containing the name of the specific Inventor engines. Please note
// that potentially not all engines are listed - new egines may have been added meanwhile.
// Please use the interaction tools function - list all engines in order to find name of engine that is not listed here
private const string InventorEngine2021 = "Autodesk.Inventor+2021"; // Inventor 2021
private const string InventorEngine2022 = "Autodesk.Inventor+2022"; // Inventor 2022
private const string InventorEngine2023 = "Autodesk.Inventor+2023"; // Inventor 2023
private const string InventorEngine2024 = "Autodesk.Inventor+2024"; // Inventor 2024
private const string InventorEngine2025 = "Autodesk.Inventor+2025"; // Inventor 2025
public static readonly string Engine = InventorEngine2025;
public const string Description = "PUT DESCRIPTION HERE";
internal static class Bundle
{
public static readonly string Id = "MachinePlannerExport";
public const string Label = "alpha";
public static readonly AppBundle Definition = new AppBundle
{
Engine = Engine,
Id = Id,
Description = Description
};
}
internal static class Activity
{
public static readonly string Id = Bundle.Id;
public const string Label = Bundle.Label;
}
internal static class Parameters
{
public const string InventorDoc = nameof(InventorDoc);
public const string OutputIpt = nameof(OutputIpt);
}
}
/// <summary>
/// Get command line for activity.
/// </summary>
private static List<string> GetActivityCommandLine()
{
return new List<string> { $"$(engine.path)\\InventorCoreConsole.exe /al \"$(appbundles[{Constants.Activity.Id}].path)\" /i \"$(args[{Constants.Parameters.InventorDoc}].path)\"" };
}
/// <summary>
/// Get activity parameters.
/// </summary>
private static Dictionary<string, Parameter> GetActivityParams()
{
return new Dictionary<string, Parameter>
{
{
Constants.Parameters.InventorDoc,
new Parameter
{
Verb = Verb.Get,
Description = "IPT file to process"
}
},
{
Constants.Parameters.OutputIpt,
new Parameter
{
Verb = Verb.Put,
LocalName = "result.ipt",
Description = "Resulting IPT",
Ondemand = false,
Required = false
}
}
};
}
/// <summary>
/// Get arguments for workitem.
/// </summary>
private static Dictionary<string, IArgument> GetWorkItemArgs()
{
// TODO: update the URLs below with real values
return new Dictionary<string, IArgument>
{
{
Constants.Parameters.InventorDoc,
new XrefTreeArgument
{
LocalName = "document.ipt",
Url = "!!! CHANGE ME !!!"
}
},
{
Constants.Parameters.OutputIpt,
new XrefTreeArgument
{
LocalName = "document.ipt",
Verb = Verb.Put,
Url = "!!! CHANGE ME !!!"
}
}
};
}
}
}

View File

@ -0,0 +1,216 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Autodesk.Forge.Core;
using Autodesk.Forge.DesignAutomation;
using Autodesk.Forge.DesignAutomation.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
namespace Interaction
{
internal partial class Publisher
{
private string _nickname;
internal DesignAutomationClient Client { get; }
private static string PackagePathname { get; set; }
/// <summary>
/// Constructor.
/// </summary>
/// <param name="configuration"></param>
public Publisher(IConfiguration configuration)
{
Client = CreateDesignAutomationClient(configuration);
PackagePathname = configuration.GetValue<string>("PackagePathname");
}
/// <summary>
/// List available engines.
/// </summary>
public async Task ListEnginesAsync()
{
string page = null;
do
{
using (var response = await Client.EnginesApi.GetEnginesAsync(page))
{
if (!response.HttpResponse.IsSuccessStatusCode)
{
Console.WriteLine("Request failed");
break;
}
foreach (var engine in response.Content.Data)
{
Console.WriteLine(engine);
}
page = response.Content.PaginationToken;
}
} while (page != null);
}
public async Task PostAppBundleAsync()
{
if (!File.Exists(PackagePathname))
throw new Exception("App Bundle with package is not found. Ensure it set correctly in appsettings.json");
var shortAppBundleId = $"{Constants.Bundle.Id}+{Constants.Bundle.Label}";
Console.WriteLine($"Posting app bundle '{shortAppBundleId}'.");
// try to get already existing bundle
var response = await Client.AppBundlesApi.GetAppBundleAsync(shortAppBundleId, throwOnError: false);
if (response.HttpResponse.StatusCode == HttpStatusCode.NotFound) // create new bundle
{
await Client.CreateAppBundleAsync(Constants.Bundle.Definition, Constants.Bundle.Label, PackagePathname);
Console.WriteLine("Created new app bundle.");
}
else // create new bundle version
{
var version = await Client.UpdateAppBundleAsync(Constants.Bundle.Definition, Constants.Bundle.Label, PackagePathname);
Console.WriteLine($"Created version #{version} for '{shortAppBundleId}' app bundle.");
}
}
public async Task RunWorkItemAsync()
{
// create work item
var wi = new WorkItem
{
ActivityId = await GetFullActivityId(),
Arguments = GetWorkItemArgs()
};
// run WI and wait for completion
var status = await Client.CreateWorkItemAsync(wi);
Console.WriteLine($"Created WI {status.Id}");
while (status.Status == Status.Pending || status.Status == Status.Inprogress)
{
Console.Write(".");
Thread.Sleep(2000);
status = await Client.GetWorkitemStatusAsync(status.Id);
}
Console.WriteLine();
Console.WriteLine($"WI {status.Id} completed with {status.Status}");
Console.WriteLine();
// dump report
var client = new HttpClient();
var report = await client.GetStringAsync(status.ReportUrl);
var oldColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.Write(report);
Console.ForegroundColor = oldColor;
Console.WriteLine();
}
private async Task<string> GetFullActivityId()
{
string nickname = await GetNicknameAsync();
return $"{nickname}.{Constants.Activity.Id}+{Constants.Activity.Label}";
}
public async Task<string> GetNicknameAsync()
{
if (_nickname == null)
{
_nickname = await Client.GetNicknameAsync("me");
}
return _nickname;
}
public async Task PublishActivityAsync()
{
var nickname = await GetNicknameAsync();
// prepare activity definition
var activity = new Activity
{
Appbundles = new List<string> { $"{nickname}.{Constants.Bundle.Id}+{Constants.Bundle.Label}" },
Id = Constants.Activity.Id,
Engine = Constants.Engine,
Description = Constants.Description,
CommandLine = GetActivityCommandLine(),
Parameters = GetActivityParams()
};
// check if the activity exists already
var response = await Client.ActivitiesApi.GetActivityAsync(await GetFullActivityId(), throwOnError: false);
if (response.HttpResponse.StatusCode == HttpStatusCode.NotFound) // create activity
{
Console.WriteLine($"Creating activity '{Constants.Activity.Id}'");
await Client.CreateActivityAsync(activity, Constants.Activity.Label);
Console.WriteLine("Done");
}
else // add new activity version
{
Console.WriteLine("Found existing activity. Updating...");
int version = await Client.UpdateActivityAsync(activity, Constants.Activity.Label);
Console.WriteLine($"Created version #{version} for '{Constants.Activity.Id}' activity.");
}
}
public async Task CleanExistingAppActivityAsync()
{
var bundleId = Constants.Bundle.Id;
var activityId = Constants.Activity.Id;
var shortAppBundleId = $"{bundleId}+{Constants.Bundle.Label}";
//check app bundle exists already
var appResponse = await Client.AppBundlesApi.GetAppBundleAsync(shortAppBundleId, throwOnError: false);
if (appResponse.HttpResponse.StatusCode == HttpStatusCode.OK)
{
//remove exsited app bundle
Console.WriteLine($"Removing existing app bundle. Deleting {bundleId}...");
await Client.AppBundlesApi.DeleteAppBundleAsync(bundleId);
}
else
{
Console.WriteLine($"The app bundle {bundleId} does not exist.");
}
//check activity exists already
var activityResponse = await Client.ActivitiesApi.GetActivityAsync(await GetFullActivityId(), throwOnError: false);
if (activityResponse.HttpResponse.StatusCode == HttpStatusCode.OK)
{
//remove exsited activity
Console.WriteLine($"Removing existing activity. Deleting {activityId}...");
await Client.ActivitiesApi.DeleteActivityAsync(activityId);
}
else
{
Console.WriteLine($"The activity {activityId} does not exist.");
}
}
private static DesignAutomationClient CreateDesignAutomationClient(IConfiguration configuration)
{
var forgeService = CreateForgeService(configuration);
var rsdkCfg = configuration.GetSection("DesignAutomation").Get<Configuration>();
var options = (rsdkCfg == null) ? null : Options.Create(rsdkCfg);
return new DesignAutomationClient(forgeService, options);
}
private static ForgeService CreateForgeService(IConfiguration configuration)
{
var forgeCfg = configuration.GetSection("Forge").Get<ForgeConfiguration>();
var httpMessageHandler = new ForgeHandler(Options.Create(forgeCfg))
{
InnerHandler = new HttpClientHandler()
};
return new ForgeService(new HttpClient(httpMessageHandler));
}
}
}

View File

@ -0,0 +1,7 @@
{
"Forge": {
"ClientId": "!!! CHANGE ME !!!",
"ClientSecret": "!!! CHANGE ME !!!"
},
"PackagePathname": "..\\..\\..\\..\\Output\\MachinePlannerExportPlugin.bundle.zip"
}

View File

@ -0,0 +1,32 @@
# Overview
This is a sample project, which allows to post app bundle, activity and work item to Design Automation services by using [.NET SDK](https://github.com/Autodesk-Forge/forge-api-dotnet-design.automation).
# Steps for test run
1. Build the whole solution.
1. (if necessary) Make `Interaction` as active project. Expand it.
1. Set Forge credentials
* Use environment variables
```
FORGE_CLIENT_ID=<your client id>
FORGE_CLIENT_SECRET=<your client secret>
```
or
```
Forge__ClientId=<your client id>
Forge__ClientSecret=<your client secret>
```
* _(not recommended)_ Open `appsettings.json` and update `ClientId` and `ClientSecret` with real values.
1. Open `Publisher.Custom.cs` and supply URLs in `GetWorkItemArgs()` method.
# Custom adjustments
The template project contains placeholders or default data for app bundle and activity. So update constants in `Publisher.Custom.cs` with your project-specific data.
# Usage
The console app can be used in two modes.
## Interaction
Launch the console and follow the instructions. Basically - each DA interaction command will have unique number, just press the required one. Command any number of commands one by one.
## Run selected command
Put number of the wanted command in command line and the console will executed it on start and exist right away. Useful if some repetetive task (like post work item) should be run frequently.

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Addin Type="Plugin">
<ClassId>{3c81698c-7325-4de9-967a-c824767c025b}</ClassId>
<ClientId>{3c81698c-7325-4de9-967a-c824767c025b}</ClientId>
<DisplayName>MachinePlannerExportPlugin</DisplayName>
<Description>a MachinePlannerExportPlugin</Description>
<Assembly>MachinePlannerExportPlugin.dll</Assembly>
</Addin>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="MachinePlannerExportPlugin" version="1.0.0.0"></assemblyIdentity>
<clrClass clsid="{3c81698c-7325-4de9-967a-c824767c025b}" progid="MachinePlannerExportPlugin.PluginServer" threadingModel="Both" name="MachinePlannerExportPlugin.PluginServer"></clrClass>
<file name="MachinePlannerExportPlugin.dll" hashalg="SHA1"></file>
</assembly>

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A4FE3963-6962-427C-AB50-E1F156A4E1C9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MachinePlannerExportPlugin</RootNamespace>
<AssemblyName>MachinePlannerExportPlugin</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autodesk.Forge.DesignAutomation.Inventor.Utils, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Autodesk.Forge.DesignAutomation.Inventor.Utils.2.0.0\lib\netstandard2.0\Autodesk.Forge.DesignAutomation.Inventor.Utils.dll</HintPath>
</Reference>
<Reference Include="autodesk.inventor.interop, Version=23.0.0.0, Culture=neutral, PublicKeyToken=d84147f8b4276564, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>$(PackagePath)\autodesk\autodesk.inventor.interop.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Log" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PluginServer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SampleAutomation.cs" />
</ItemGroup>
<ItemGroup>
<None Include="MachinePlannerExportPlugin.X.manifest" />
<Content Include="PackageContents.xml" />
<Content Include="MachinePlannerExportPlugin.Inventor.addin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
-->
<Target Name="AfterBuild">
<ItemGroup>
<PluginBundle Include="$(TargetDir)*.*" />
</ItemGroup>
<Copy SourceFiles="$(ProjectDir)PackageContents.xml" DestinationFolder="$(TargetDir)..\Bundle\$(MSBuildProjectName).bundle" />
<Copy SourceFiles="@(PluginBundle)" DestinationFolder="$(TargetDir)..\Bundle\$(MSBuildProjectName).bundle\Contents\" />
<MakeDir Directories="$(ProjectDir)..\Output" />
<ZipDirectory SourceDirectory="$(TargetDir)..\Bundle" DestinationFile="$(ProjectDir)..\Output\$(MSBuildProjectName).bundle.zip" Overwrite="true" />
</Target>
</Project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage SchemaVersion="1.0" Version="1.0" ProductCode="{3c81698c-7325-4de9-967a-c824767c025b}" Name="MachinePlannerExportPlugin" Description="MachinePlannerExportPluginPlugin Plugin" Author="Inventor IO Dev">
<CompanyDetails Name="Autodesk, Inc" Phone="415.555.5555" Url="www.autodesk.com" Email="noreply@autodesk.com" />
<Components>
<!-- For Inventor Engine, "Platform" attribute must be "Inventor" -->
<RuntimeRequirements OS="Win64" Platform="Inventor" />
<!-- For Inventor Plug-in, the "Module" attribute must point to the .addin manifest file. -->
<ComponentEntry LoadOnAutoCADStartup="False" LoadOnCommandInvocation="False"
AppDescription="MachinePlannerExportPlugin App Package."
ModuleName="./Contents/MachinePlannerExportPlugin.Inventor.addin" AppName="MachinePlannerExportPlugin"/>
</Components>
<EnvironmentVariables>
</EnvironmentVariables>
</ApplicationPackage>

View File

@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by Forge Partner Development
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
/////////////////////////////////////////////////////////////////////
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using Inventor;
namespace MachinePlannerExportPlugin
{
[Guid("3c81698c-7325-4de9-967a-c824767c025b")]
public class PluginServer : ApplicationAddInServer
{
// Inventor application object.
private InventorServer _inventorServer;
public dynamic Automation { get; private set; }
public void Activate(ApplicationAddInSite addInSiteObject, bool firstTime)
{
Trace.TraceInformation(": MachinePlannerExportPlugin (" + Assembly.GetExecutingAssembly().GetName().Version.ToString(4) + "): initializing... ");
// Initialize AddIn members.
_inventorServer = addInSiteObject.InventorServer;
Automation = new SampleAutomation(_inventorServer);
}
public void Deactivate()
{
Trace.TraceInformation(": MachinePlannerExportPlugin: deactivating... ");
// Release objects.
Marshal.ReleaseComObject(_inventorServer);
_inventorServer = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
public void ExecuteCommand(int CommandID)
{
// obsolete
}
}
}

View File

@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MachinePlannerExportPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Autodesk Inc.")]
[assembly: AssemblyProduct("MachinePlannerExportPlugin")]
[assembly: AssemblyCopyright("Copyright © Autodesk Inc. 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f1c9d7e2-53a8-4e4e-af9e-931ca891715d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,124 @@
/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by Forge Partner Development
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
/////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Autodesk.Forge.DesignAutomation.Inventor.Utils;
using Autodesk.Forge.DesignAutomation.Inventor.Utils.Helpers;
using Inventor;
namespace MachinePlannerExportPlugin
{
[ComVisible(true)]
public class SampleAutomation
{
private readonly InventorServer inventorApplication;
public SampleAutomation(InventorServer inventorApp)
{
inventorApplication = inventorApp;
}
public void Run(Document doc)
{
LogTrace("Run called with {0}", doc.DisplayName);
}
public void RunWithArguments(Document doc, NameValueMap map)
{
LogTrace("Processing " + doc.FullFileName);
try
{
// Using NameValueMapExtension
if (map.HasKey("intIndex"))
{
int intValue = map.AsInt("intIndex");
LogTrace($"Value of intIndex is: {intValue}");
}
if (map.HasKey("stringCollectionIndex"))
{
IEnumerable<string> strCollection = map.AsStringCollection("stringCollectionIndex");
foreach (string strValue in strCollection)
{
LogTrace($"String value is: {strValue}");
}
}
if (doc.DocumentType == DocumentTypeEnum.kPartDocumentObject)
{
using (new HeartBeat())
{
// TODO: handle the Inventor part here
}
}
else if (doc.DocumentType == DocumentTypeEnum.kAssemblyDocumentObject) // Assembly.
{
using (new HeartBeat())
{
// TODO: handle the Inventor assembly here
}
}
}
catch (Exception e)
{
LogError("Processing failed. " + e.ToString());
}
}
#region Logging utilities
/// <summary>
/// Log message with 'trace' log level.
/// </summary>
private static void LogTrace(string format, params object[] args)
{
Trace.TraceInformation(format, args);
}
/// <summary>
/// Log message with 'trace' log level.
/// </summary>
private static void LogTrace(string message)
{
Trace.TraceInformation(message);
}
/// <summary>
/// Log message with 'error' log level.
/// </summary>
private static void LogError(string format, params object[] args)
{
Trace.TraceError(format, args);
}
/// <summary>
/// Log message with 'error' log level.
/// </summary>
private static void LogError(string message)
{
Trace.TraceError(message);
}
#endregion
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autodesk.Forge.DesignAutomation.Inventor.Utils" version="2.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
</packages>