如果在VB.NET

时间:2019-01-02 14:02:37

标签: vb.net shell

我正在使用COM接口从第三方程序中导出动画。我正在使用Shell命令从我的工具发送带有脚本的导出COM命令。

我将动画导出命令发送给第三方工具时出现问题。它开始导出,但是我的工具正在发送第二个动画导出命令,而最后一个未完成。如何防止这种情况发生?

文件创建后,我想从for循环中发送我的shell命令。

我的代码如下。

Private Sub tlbCheckSolveEvaCtrl_exportmodeshape_Click(sender As Object, e As EventArgs) Handles tlbCheckSolveEvaCtrl_exportmodeshape.Click
    Try
        Dim strArgument As String

        Dim strfilePathEV As String
        Dim strfilePathANI As String
        Dim strfilePathPIC As String

        strfilePathEV = strProjMdlDir & My.Settings.txtCheckSolverOuputDir & strProjMdlName & ".ev.sbr"
        strfilePathANI = strProjMdlDir & "\" & My.Settings.txtProjDirDOC & "\" & My.Settings.txtProjDirANI & "\"
        strfilePathPIC = strProjMdlDir & "\" & My.Settings.txtProjDirDOC & "\" & My.Settings.txtProjDirPIC & "\"

        For i As Integer = 0 To dgvCheckSolveEva.RowCount - 1
            strArgument = strfilePathEV & " " & _
                strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
                i
            Shell(My.Settings.txtSpckDir & "simpack-post.exe -s qs_mode_shape.qs " & strArgument)
        Next


    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

如果创建了动画文件for,我想继续进行strfilePathANI & strProjMdlName & "_" & i & ".mpg"循环,以便可以开始导出下一个动画文件。

1 个答案:

答案 0 :(得分:5)

最好的方法是使用.NET Process class并调用WaitForExit() method,以等待simpack-post.exe关闭。

Shell()是VB6-era的过时功能,其存在纯粹是为了与该语言部分向后兼容。不应在新代码中使用它。

基本示例:

Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()

当然,此问题是它可能会阻塞UI线程,从而导致其冻结,具体取决于进程退出需要多长时间。因此,我们应该将其包装在Task中:

Dim c As Integer = dgvCheckSolveEva.RowCount - 1

Task.Run( _
    Sub()
        For i As Integer = 0 To c
            strArgument = strfilePathEV & " " & _
                strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
                i

            Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
            Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()
        Next
    End Sub _
)

请注意,您不能从任务内直接访问UI。如果要这样做,则需要Invoke


编辑:

如果目标是.NET Framework 3.5或更低版本,或者使用VS 2008或更低版本,则任务不可用,我们不得不求助于使用常规线程和/或常规方法来代替lamba表达式。

请注意,同样的规则适用-您必须先调用才能访问UI。

使用VS 2010(及更高版本)的.NET 3.5(或更低版本):

Dim c As Integer = dgvCheckSolveEva.RowCount - 1

Dim t As New Thread( _
    Sub()
        For i As Integer = 0 To c
            strArgument = strfilePathEV & " " & _
                strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
                i

            Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
            Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()
        Next
    End Sub _
)
t.IsBackground = True
t.Start()

使用VS 2008(或更低版本)的.NET 3.5(或更低版本):

Private Sub tlbCheckSolveEvaCtrl_exportmodeshape_Click(sender As Object, e As EventArgs) Handles tlbCheckSolveEvaCtrl_exportmodeshape.Click

    ...your code...

    Dim c As Integer = dgvCheckSolveEva.RowCount - 1
    Dim t As New Thread(New ParameterizedThreadStart(AddressOf ExportAnimationsThread))
    t.IsBackground = True
    t.Start(c)

    ...your code...
End Sub

Private Sub ExportAnimationsThread(ByVal Count As Integer)
    For i As Integer = 0 To Count
        strArgument = strfilePathEV & " " & _
            strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
            i

        Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
        Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()
    Next
End Sub