In order to run programmatically Inventor from an external application, you would typically rely on code that looks like this in order to access a reference of Inventor.Application:
Type inventorAppType =
System.Type.GetTypeFromProgID(
"Inventor.Application");
Inventor.Application app =
System.Activator.CreateInstance(
inventorAppType)
as Inventor.Application;
With AutoCAD it is possible to launch a specific version of the product if you have several releases installed side by side on the machine, by specifying the version along with the ProgId, for example “AutoCAD.Application.19.1” will launch AutoCAD 2014.
However this versioning mechanism doesn’t apply to Inventor, so how would you fire a specific version of Inventor from your Exe?
The small utility class below exposes two different workarounds that contain similarities:
. AdnInventorLoader.CreateInstanceFromProcess:
This method will read a specific registry entry depending on the version you passed as argument in order to extract the full path of the desired Inventor.exe. It will then start a new process from that path and use GetActiveObject to retrieve the running instance of Inventor.
. AdnInventorLoader.CreateInstanceFromCLSID:
This method will also retrieve the path of Inventor.exe from the registry, but instead of launching a new process, it will update the path of the last run version of Inventor inside the CLASSES_ROOT hive of the registry and will fire Inventor using CreateInstance.
You may prefer using the first method, as modifying the CLASSES_ROOT entries may require admin or specific privileges that user doesn’t necessarily have.
// Utility Class to launch specific version
// of Inventor Application
// By Philippe Leefsma, May 2013 – Devtech
class AdnInventorLoader
{
public enum Version
{
Inventor_2010,
Inventor_2011,
Inventor_2012,
Inventor_2013,
Inventor_2014
};
public static Inventor.Application
CreateInstanceFromProcess(Version version)
{
try
{
string exePath = GetExePath(version);
if (exePath != string.Empty)
{
CleanUpRegistry();
System.Diagnostics.Process process =
System.Diagnostics.Process.Start(
exePath);
if (process != null)
{
//Wait for 5 Mins
if (process.WaitForInputIdle(
300000))
{
while(true)
{
try
{
Inventor.Application app =
Marshal.GetActiveObject(
"Inventor.Application")
as Inventor.Application;
return app;
}
catch (Exception ex)
{
if (!ex.Message.Contains(
"MK_E_UNAVAILABLE"))
break;
System.Threading.Thread.
Sleep(1000);
}
}
}
}
}
return null;
}
catch
{
return null;
}
}
public static Inventor.Application
CreateInstanceFromCLSID(Version version)
{
try
{
string exePath = GetExePath(version);
if (exePath != string.Empty)
{
CleanUpRegistry();
using (RegistryKey inventorKey =
Registry.ClassesRoot.
OpenSubKey("CLSID").
OpenSubKey("").
OpenSubKey("LocalServer32",
true))
{
string[] names =
inventorKey.GetValueNames();
inventorKey.SetValue(
names[0],
exePath + " /Automation");
inventorKey.Close();
Type inventorAppType =
System.Type.GetTypeFromProgID(
"Inventor.Application");
Inventor.Application app =
System.Activator.CreateInstance(
inventorAppType)
as Inventor.Application;
return app;
}
}
return null;
}
catch
{
return null;
}
}
// Clean up registry to prevent
// "Re-registration" dialog
private static bool CleanUpRegistry()
{
try
{
using (RegistryKey inventorKey =
Registry.CurrentUser.
OpenSubKey("Software").
OpenSubKey("Autodesk").
OpenSubKey("Inventor").
OpenSubKey("Current Version",
true))
{
if (inventorKey == null)
return false;
inventorKey.DeleteValue(
"Executable");
inventorKey.DeleteValue(
"LastVersionRun");
inventorKey.DeleteValue(
"Registered");
inventorKey.DeleteValue(
"RegistryVersion");
inventorKey.DeleteValue(
"SilentMode");
inventorKey.DeleteValue(
"UBI");
inventorKey.Close();
return true;
}
}
catch
{
return false;
}
}
// Retrieve Inventor.exe fullpath based on version
private static string GetExePath(Version version)
{
try
{
string key = string.Empty;
switch (version)
{
case Version.Inventor_2010:
key = "RegistryVersion14.0";
break;
case Version.Inventor_2011:
key = "RegistryVersion15.0";
break;
case Version.Inventor_2012:
key = "RegistryVersion16.0";
break;
case Version.Inventor_2013:
key = "RegistryVersion17.0";
break;
case Version.Inventor_2014:
key = "RegistryVersion18.0";
break;
default:
return string.Empty;
}
using(RegistryKey inventorKey =
RegistryKey.OpenBaseKey(
Microsoft.Win32.RegistryHive.LocalMachine,
RegistryView.Registry64).
OpenSubKey("SOFTWARE").
OpenSubKey("Autodesk").
OpenSubKey("Inventor").
OpenSubKey(key))
{
if (inventorKey == null)
return string.Empty;
string path = inventorKey.GetValue(
"InventorLocation")
as string;
inventorKey.Close();
path += "Inventor.exe";
return (System.IO.File.Exists(path) ?
path :
string.Empty);
}
}
catch
{
return string.Empty;
}
}
}
Here are examples of use for both methods:
Inventor.Application app =
AdnInventorLoader.CreateInstanceFromProcess(
AdnInventorLoader.Version.Inventor_2013);
if (app != null)
app.Visible = true;
-------------------------
Inventor.Application app =
AdnInventorLoader.CreateInstanceFromCLSID(
AdnInventorLoader.Version.Inventor_2014);
if (app != null)
app.Visible = true;