Running programmatically a specific version of Inventor

By Philippe Leefsma

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

    // http://tinyurl.com/dx4tsnu

    private static bool CleanUpRegistry()

    {

        try

        {

            using (RegistryKey inventorKey =

                Registry.CurrentUser.

                    OpenSubKey("Soft
ware"
).

                    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;


Comments

One response to “Running programmatically a specific version of Inventor”

  1. Philippe, I’m using this process to start our Inventor 2014 Pro. When I use the ‘CreateInstanceFromProcess’, it works to start a new process of Inventor2014… But I can’t get the handle to that process; the Marshal.GetActiveObject continuously fails no matter how long it runs. Then if I use the CreateInstanceFromCLSID… I get an error as the System.Type.GetTypeFromProgID(“Inventor.Application”) fails to return a system.type What exactly is the GetTypeFromProgID looking for in the registry? I have an entry for Inventor.Application, but what subkey under there is it try to acquire?

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading