hexagon logo

vb.net how to execute part program and handle inputs

I'm trying to write a vb.net program to assist in updating our programs from V3.5MR2 to 2010MR3 and standardizing probe names. I have my program doing most of what I want except when executing the program most programs have operator inputs and I can't get past them without manual intervention. I can set the values in my vb.net program using .CommentCommand.Input but how do I either get it to not prompt for the input or "click ok" on the dialog? I'm using .ActivePartProgram.EXECUTE. Should I be using something else?

Any help would be greatly appreciated.
  • Yes. They want to execute the part program to check for any errors that might have been introduced by the update.
  • Check out SendKeys() which allows you to "emulate" keypresses from a keyboard. Sending TAB should move your selection/focus so you should be able to "move" and select textboxes/buttons for input/click without using the mouse.
  • I thought about that... We have many programs with many different inputs so I was hoping that there was a way to skip the inputs and just run the program.
    Do you know of a way to know if it is waiting for input other than looking for a window handle?
  • Maybe you can use marked sets and mark the inputs section of the program and run the rest?

    Or, use a variable that you set at the beginning (through your script) and check for that variables value just prior to displaying the input boxes.

    Pseudocode:

    Run your script.
    (script is doing stuff)
    Script sets the variable "SKIPIT" to "1" in the beginning of the program.
    Just before the input boxes are displayed, you have a snippet that checks for the value of "SKIPIT", if the value is anything but "1" then the input boxes should display (ie. you want them to display), if the value is "1", the input boxes should be skipped (look up "labels" and "goto") and the program should be executed.
  • I was able to get it to work by using ApplicationObjectEvents. I first watched all available events and found that OnOpenRemotePanelDialog gets fired when the input box is displayed and found machine object PressDone that clicks the OK button. I found that OnUpdateStatusMessage reports "Execution complete" when the program is done executing so I created a while loop that clicks the continue button until completion reported.

    Here is my program that changes the probe name, adds a revision line, removes Print report and executes the program.

    '
    ' copied from http://www.pcdmisforum.com/showthread.php?26953-Script-to-make-a-change-in-all-programs/page2
    ' original creator ewe0006 01-09-2014
    ' modified 07-16-2014
    '
    '
    Public Class Form1
    
    
        Const ProgramDir = "C:\Users\Public\Documents\WAI\PC-DMIS\2010 MR3\"
        Const ProgramFileExt = "*.PRG"
    
        Private pcdApp As PCDLRN.Application
        Dim WithEvents AppEvents As PCDLRN.ApplicationObjectEvents
        Private pcdParts As PCDLRN.PartPrograms
        Private pcdActivePart As PCDLRN.PartProgram
        Private pcdCommands As PCDLRN.Commands
        Private pcdCommand As PCDLRN.Command
        Private pcdNextCommand As PCDLRN.Command
        Private pcdActiveCommand As PCDLRN.CommandsClass
        Private pcdMachine As PCDLRN.Machine
        Private pcdExecuteWindow As PCDLRN.ExecutionWindow
        Dim progExecuteOk As Boolean = False
        Private ChangeList As New List(Of String)
    
    
    Private Sub Form1_Load( ByVal sender As System.Object,  ByVal e As System.EventArgs) Handles MyBase.Load
    
    End Sub
    
    Private Sub Button1_Click( ByVal sender As System.Object,  ByVal e As System.EventArgs) Handles Button1.Click
    
    	If ConnectPCD() = True Then
                Dim tmpFiles() As String = GetFiles(ProgramDir)
                Try
                    For Each tmpFile As String In tmpFiles
                        If ChangeProbeNames(tmpFile) = False Then Exit For
                    Next
                Catch ex as Exception
                    Console.Writeline(ex.Message)
                End Try
                Console.WriteLine("Complete!")
            End If
    
            DisconnectPCD()
    
    End Sub
    
        Function GetFiles(ByVal RootDir As String) As String()
    
            Return Directory.GetFiles(RootDir, ProgramFileExt, SearchOption.AllDirectories)
    
        End Function
    
        Function ConnectPCD() As Boolean
            Try
                pcdApp = GetObject("", "PCDLRN.Application")
                pcdApp.WaitUntilReady(60)
                Thread.Sleep(2000)
                pcdApp.Visible = True
                pcdApp.Maximize()
    			
    			While pcdApp.PartPrograms.Count <> 0
    				pcdApp.ActivePartProgram.Quit()
    	            Thread.Sleep(2000)
    			End While
    
                pcdParts = pcdApp.PartPrograms
                Return True
            Catch ex As Exception
                Console.WriteLine("ConnectPCD : " & ex.Message)
                Return False
                pcdParts = Nothing
                pcdApp = Nothing
                GC.Collect()
            End Try
    
        End Function
    
        Sub DisconnectPCD()
    
            pcdCommand = Nothing
            pcdCommands = Nothing
            pcdActivePart = Nothing
            pcdParts = Nothing
            pcdApp = Nothing
            GC.Collect()
    
        End Sub
    
    
    
        Function ChangeProbeNames(ByVal FilePath As String) As Boolean
    
    
        Console.WriteLine("Converting file: " & FilePath)
    
        Try
            pcdParts.Open(FilePath, "CMM1")
            pcdActivePart = pcdApp.ActivePartProgram
            pcdCommands = pcdActivePart.Commands
    		Dim pcdExecutedCommands As Object
    		pcdExecutedCommands = pcdActivePart.ExecutedCommands
    
    		Dim curDate As String = Format(Now, "MM-dd-yy")
    		Dim userIni As String = String.Empty
    		progExecuteOk = False
    		For i As Integer = 0 To pcdCommands.Count
    			pcdCommand = pcdCommands.Item(i)
    			If pcdCommand Is Nothing Then Continue For
    			
    			Select Case pcdCommand.Type
    				'If command is a comment we need to check if it is revsion history so we can add a new line to it.
    				Case PCDLRN.OBTYPE.SET_COMMENT
    					Dim at As Integer
    					Dim insertPnt As Integer
    					Dim comString = pcdCommand.CommentCommand.Comment
    					'The is what the revision history comment looks like.
    					'------------------------------------------------------------------------------------------------
    					'
    					'BY:    DATE:    DESCRIPTION:
    					'
    					'------------------------------------------------------------------------------------------------
    					'
    					'JJ     01/01/10 New Program
    					'
    					'------------------------------------------------------------------------------------------------
    					'The following looks for a Document Comment that contains certain strings that are in the revision history comment.
    					If comString.ToLower.Contains("by:") AND comString.ToLower.Contains("date:") AND comString.ToLower.Contains("description:") AND pcdCommand.GetFieldValue(PCDLRN.ENUM_FIELD_TYPES.COMMENT_TYPE, 0) = "$$" Then
    						at = 0
    						at = comString.LastIndexOf("------")
    						If at > 0 Then
    							insertPnt = comString.LastIndexOf(vbCrLf, at-1)
    							If insertPnt > 0 Then
    								comString = comString.Insert(insertPnt, userIni & "     " & curDate & " Changed probe names" & vbCrLf)
    								pcdCommand.CommentCommand.Comment = comString
    							Else
    								MsgBox("unable to find comment section",,"Error")
    								Return False
    							End If
    						Else
    							MsgBox("unable to find comment section",,"Error")
    							Return False
    						End If
    					End If
    				'If the command is probe we need to switch the filename used
    				Case PCDLRN.OBTYPE.GET_PROBE_DATA
    					Select Case pcdCommand.LoadProbeCommand.FileName
    						Case "PROBE1"
    							ChangeProbeFile(pcdCommand, pcdCommands.Item(i+1), "PROBE1MM", "PROBE1")
    					    Case Else
    							MessageBox.Show("No Mapping for probe " & pcdCommand.LoadProbeCommand.FileName, "Error !", MessageBoxButtons.OK,MessageBoxIcon.Error)
    					End Select
    				'If the command is Print Report lets remove is since it is no longer needed.
    			    Case PCDLRN.OBTYPE.PRINT_REPORT
    					If pcdCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.PRINT_TO_PRINTER, 1) = "ON" Then
    						ChangeList.Add("Removed Print Report")
    						pcdCommand.Remove()
    					End If
    			    Case Else
    			End Select
            Next
    
    		'This starts the application events firing so we can see what PC-DMIS is doing.
    		AppEvents = pcdApp.ApplicationEvents
    
    		'create a machine so we can press done on input/comment boxes.
    		pcdMachine = pcdApp.ActivePartProgram.ActiveMachine
    
    		'run the program
    		pcdActivePart.AsyncExecute()
    
    		'loop until program execution is complete
    		While Not progExecuteOk
                Threading.Thread.Sleep(500)
    			Try
    				pcdExecuteWindow.Continue
    				Console.WriteLine("Not progExecuteOk")
    			Catch ex As Exception
    				Console.WriteLine("Not progExecuteOk exception : " & ex.Message)
    			End Try
    		End While
    
    		'Turn off application events
    		AppEvents = Nothing
    
    		'save the part program and close it
    		pcdActivePart.Close()
            Thread.Sleep(2000)
    		'quit the program without saving the part program
    		'pcdActivePart.Quit()
            Return True
        Catch ex As Exception
            Console.WriteLine("ConvertUpdateProbe Exception: " & ex.Message)
            Return False
        End Try
    
    End Function
    
    
    Function ChangeProbeFile(ByVal pcdCommand As PCDLRN.Command, ByVal pcdNextCommand As PCDLRN.Command, ByRef probeNewName As String, ByRef probeOldName As String) As Boolean
    'This function changes the Probe name and checks for a set active tip command on the next command. If not found add an active tip
    	Try
    		Dim RetVal As Boolean
    		ChangeList.Add("Changed " & probeOldName & " to " & probeNewName)
    		pcdCommand.LoadProbeCommand.FileName = probeNewName
    		If pcdNextCommand.Type <> PCDLRN.OBTYPE.SET_ACTIVE_TIP Then
    			pcdCommands.InsertionPointAfter(pcdCommand)
    			pcdCommand = pcdCommands.Add(PCDLRN.OBTYPE.SET_ACTIVE_TIP, TRUE)
    			pcdCommand.Marked = TRUE
    			retval = pcdCommand.PutText ("T1A0B0", PCDLRN.ENUM_FIELD_TYPES.ID, 0)
    		ChangeList.Add("Added tip T1A0B0")
    		End If
    	    Return True
    	Catch ex As Exception
    		Return False
    	End Try
    End Function
    
    Private Sub AppEvents_OnObjectExecuted( ByVal pp As  PCDLRN.IPartProgram, ByVal cmd As PCDLRN.ICommand) Handles AppEvents.OnObjectExecuted
    		Console.WriteLine("OnObjectExecuted : " & cmd.CommentCommand.Comment)
    		Try
    			pcdExecuteWindow = pp.GetExecutionWindow(0)
    		Catch ex As Exception
    			Console.WriteLine("Exception in AppEvents_OnObjectExecuted : " & ex.Message)
    		End Try
    End Sub
    
    
    Private Sub AppEvents_OnOpenRemotePanelDialog( ByVal pp As  PCDLRN.IPartProgram, ByVal DI As Long, ByVal winHand As Long, ByVal panMess As String, ByVal btn1 As Long, ByVal btn2 As Long, ByVal btn3 As Long, ByVal btn4 As Long, ByVal dfltbtn As Long) Handles AppEvents.OnOpenRemotePanelDialog
    		Console.WriteLine("OnOpenRemotePanelDialog : " & panMess)
    			pcdMachine.PressDone
    End Sub
    
    Private Sub AppEvents_OnUpdateStatusMessage( ByVal statMess As  String) Handles AppEvents.OnUpdateStatusMessage
    		Console.WriteLine("OnUpdateStatusMessage : " & statMess)
    		If statMess = "Execution complete" Then
    			progExecuteOk = True
    		End If
    End Sub
    
    End Class