0

I'm using a COM interface to export animations from a third-party program. I'm sending an exporting COM command with script from my tool with a shell command.

There's a problem with when I send the animation export command to the third-party tool. It starts to export, but my tool is sending a second animation export command while the last one is not finished. How can I prevent from this situation?

I'd like to sending my shell command from the for loop after the file was created.

My code is like below.

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

I'd like to continue my for loop if strfilePathANI & strProjMdlName & "_" & i & ".mpg", the animation file was created, so I can start to export the next one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

1 Answers1

4

The best way would be to use the .NET Process class and call the WaitForExit() method in order to wait for simpack-post.exe to close itself.

Shell() is an outdated function from the VB6-era which exists purely for partial backwards compatibility with that language. It shouldn't be used in new code.

Basic example:

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

The problem with this of course is that it might block the UI thread and thus cause it to freeze, depending on how long it takes for the process to exit. Therefore we should wrap it in a 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 _
)

Just note that you cannot directly access the UI from within the task. If you want to do so you need to Invoke.


EDIT:

If you are targeting .NET Framework 3.5 or lower, or using VS 2008 or lower, tasks aren't available and we have to resort to using regular threads and/or regular methods instead of lamba expressions.

Note that the same rules apply, though - you cannot access the UI without invoking.

.NET 3.5 (or lower) using VS 2010 (and higher):

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()

.NET 3.5 (or lower) using VS 2008 (or lower):

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
Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
  • And you are assuming the OP is targeting > 4.0 framework... :) – Trevor Jan 02 '19 at 16:52
  • @Çöđěxěŕ : Even though there will always be exceptions, .NET 3.5 and below are fading away more and more these days. So until stated otherwise, yes I am :). But if you're concerned about it I'll edit the answer and include a .NET 3.5 and VS 2008 solution as well. – Visual Vincent Jan 02 '19 at 17:09
  • Haha, no I am not concerned; great solution BTW. – Trevor Jan 02 '19 at 17:15
  • 1
    @Çöđěxěŕ : Too late, added it anyway ;). Also, thanks! – Visual Vincent Jan 02 '19 at 17:22
  • @VisualVincent thanks for the great post im using VB2012 and framework 4.5.2 but before that i have to thank you a lot and i'll test how your guides work. –  Jan 02 '19 at 18:02
  • 1
    @Çöđěxěŕ Where is the upvote for the "great solution"? – Mary Jan 02 '19 at 18:17
  • @Hakan : Take your time, and let me know if you have any problems! – Visual Vincent Jan 02 '19 at 22:16
  • @VisualVincent i used your edited version and it's working really good. thank you my friend. –  Jan 03 '19 at 06:51
  • @Hakan : Glad I could help, but I'm curious as to what exactly you refer to as my _"edited version"_? Do you mean the .NET 3.5/VS 2008 compatible solutions, or just my version of your code? _If_ the former, why would you use those if you're already targeting a newer framework? :) – Visual Vincent Jan 03 '19 at 08:08
  • @VisualVincent sorry i wrote wrong non-edited version i mean –  Jan 03 '19 at 08:12
  • @Hakan : Okay, just wanted to make sure as the .NET 3.5 solutions aren't really best practice these days :). Glad I could help, and good luck with your project! – Visual Vincent Jan 03 '19 at 08:14