大多数情况下,一台机器上可能会装有几个版本的Inventor,尤其开发者的机器。我同事写了篇文章,介绍如何启动特定版本的Inventor。原文地址:
Running programmatically a specific version of Inventor
大家知道,从独立应用程序(EXE)启动Inventor,基本步骤如下。从注册表找到Inventor Application组件信息,然后调用CreateInstance启动。
Type inventorAppType =
System.Type.GetTypeFromProgID(
"Inventor.Application");
Inventor.Application app =
System.Activator.CreateInstance(
inventorAppType)
as Inventor.Application;
若你做过AutoCAD二次开发,可能知道,AutoCAD也有COM API,也能实现启动AutoCAD进程,而且能够指定版本,形如 “AutoCAD.Application.19.1”,将启动AutoCAD 2014. 但Inventor无此机制。那么要启动特定版本的Inventor,如何做呢?以下是个我们提供的工具类AdnInventorLoader, 提供了两种方式:
AdnInventorLoader.CreateInstanceFromProcess
该方法将读取特定版本Inventor注册信息,然后获取到对应Inventor.exe所在路径,最后启动该exe。
AdnInventorLoader.CreateInstanceFromCLSID
该方法也是先读取特定版本Inventor注册信息,然后获取到对应Inventor.exe所在路径。但接着它并不是直接启动exe,而是去改变最后一次启动的Inventor版本。当然,该方法可能需要管理员权限或特别的用户权限。
因此,可能方法1更适合你。
// 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))
{
Inventor.Application app =
Marshal.GetActiveObject(
"Inventor.Application")
as Inventor.Application;
return app;
}
}
}
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
// http://tinyurl.com/dx4tsnu
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 =
Registry.LocalMachine.
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;