用程序启动Inventor失败的原因和解决方法

时候用 "CreateObject("Inventor.Application")"来启动Inventor会失败,但是随后再执行这个命令时Inventor又会成功启动,这是怎么回事?下面是我们的技术专家的解释以及解决办法:

Inventor starts up very slowly when none of its DLLs are in the system's file cache. Restarting the computer clears the file cache so that the first instantiation of Inventor takes a very long time to initialize. When Inventor is started via automation, it must call CoRegisterClassObject within two minutes of the process starting, or else COM assumes the process failed to start and raises a CO_E_SERVER_EXEC_FAILURE 0x80080005 exception in the calling program. This has the effect of killing the inventor.exe process providing the caller with a useless pointer/reference and potentially an unhandled exception. Subsequent attempts to start inventor.exe will use the DLLs in the file cache and the process generally starts much more quickly and does not time out

 

You can pre-load the libraries by running and exiting Inventor prior to running a utility program. This process is generally needed only one time after each computer restart; subsequent use of the utility programs will reuse the cached libraries loaded earlier in the Windows session. If you have multiple releases of Inventor installed, be sure to run and exit the Inventor release that matches the version number of the utility program you would like to run. Running and exiting a specific release of Inventor will set a value in the Windows registry so the utility programs can detect which installation is active.

 

An alternative solution is to launch Inventor as a local COM server: in this case the timeout can be up to three minutes and it is generally enough to allow the process to run. The following VB.NET sample shows how to accomplish this.

 

解决办法如下:

   

Imports Microsoft.Win32

 

Public Class clsLocalSrv

 

    Public Shared Function StartAsLocalServer(ByVal ProgId As String, _

 

                                               ByVal nMilliSeconds As Integer, _

 

                                               ByRef oApplication As Object) As Boolean

 

 

        Dim enUS As New Globalization.CultureInfo("en-US")

 

        Threading.Thread.CurrentThread.CurrentCulture = enUS

 

 

        Dim commandName As String = ""

 

        Dim arguments As String = ""

 

 

        Dim oRegKey As Microsoft.Win32.RegistryKey, oCls As Microsoft.Win32.RegistryKey

 

        Dim oVal As Object, sName As String, oDir As Object

 

        Try

 

            oCls = Registry.ClassesRoot

 

            oRegKey = oCls.OpenSubKey(ProgId + "//CLSID", False)

 

            oVal = oRegKey.GetValue("", Nothing)

 

            oRegKey = oCls.OpenSubKey("CLSID//" & oVal & "//LocalServer32", False)

 

            oDir = oRegKey.GetValue("", Nothing)

 

 

            oRegKey.Close()

 

            oCls.Close()

 

            sName = oDir

 

 

            Dim nIndex As Long

 

            nIndex = Microsoft.VisualBasic.InStrRev(sName, "/automation", , CompareMethod.Text)

 

            commandName = Microsoft.VisualBasic.Left(sName, nIndex - 1)

 

            arguments = Microsoft.VisualBasic.Right(sName, (sName.Length() - nIndex + 1))

 

        Catch ex As Exception

 

            MsgBox(ex.Message)

 

            Exit Function

 

        End Try

 

        ' Start the program

 

        Dim oProcess As Process = Process.Start(commandName, arguments)

 

        ' Loop until run out of time or get the process's object.

 

        Dim Start, Finish As Double

 

        Start = Microsoft.VisualBasic.DateAndTime.Timer

 

        Finish = Start + (nMilliSeconds / 1000)

 

 

        Do While Microsoft.VisualBasic.DateAndTime.Timer < Finish

 

            Try

 

                oApplication = System.Runtime.InteropServices.Marshal.GetActiveObject(ProgId)

 

                If Not oApplication Is Nothing Then

 

                    Return True

 

                End If

 

            Catch ex As Exception

 

                ' Keep trying until run out of time

 

            End Try

 

            System.Threading.Thread.Sleep(100)

 

        Loop

 

        ' Failed to get the running object, stop the process

 

        oProcess.Kill()

        Return False

    End Function

End Class

 

在你的程序里调用上面的方法:

 

If clsLocalSrv.StartAsLocalServer("Inventor.Application", 120000, m_inventorApp) = True Then

 

   '...

End If

 

如果你用的不是VB.NET,而是VB,那么替换的办法也许是用定时器(Timer)来替代上面的Thread,并用GetObject来替换上面的System.Runtime.InteropServices.Marshal.GetActiveObject来做类似的工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值