Testing if SysCAD is open in VBA (COM Automation)
|Command Scripts||COM Automation||Python Automation||VBA Automation||C++ Automation||Testing if SysCAD is open|
Generally a COM Automation macro is written to start SysCAD, load a project, perform some actions, close SysCAD. For this to work correctly and reliably, SysCAD should NOT be open when executing the Macro. Using "Set App = New ScdApplication" to try hook into an already open copy of SysCAD (especially if it has a project open or if more than one copy of SysCAD is open) is likely to lead to unpredictable results.
A few lines of code at the start of the Macro can test if SysCAD is already open. If it is open then give a message and exit the Macro. See VBA Automation example for an example of how this could be included. Code segment to test for open copies of SysCAD:
Sub ProBalExample() If SysCADProcessesRunning <> 0 Then MsgBox "SysCAD is open! Please close all copies of SysCAD (and/or SysCAD processes)." Exit Sub End If 'do stuff... '== Start SysCAD.. Set App = New ScdApplication 'Continue... End Sub
The code for the function SysCADProcessesRunning is shown below. It is recommended that a separate Module is added to the VBA project and the code below pasted into this module.
VBA Code to check for Open SysCAD application or Process
Recommendation: Place this into a separate VBA Module so that the main VBA code isn't cluttered with this helper function.
Option Explicit Const TH32CS_SNAPHEAPLIST = &H1 Const TH32CS_SNAPPROCESS = &H2 Const TH32CS_SNAPTHREAD = &H4 Const TH32CS_SNAPMODULE = &H8 Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE) 'Const TH32CS_INHERIT = &H80000000 Const MAX_PATH As Integer = 260 Private Type PROCESSENTRY32 dwSize As Long cntUsage As Long th32ProcessID As Long th32DefaultHeapID As Long th32ModuleID As Long cntThreads As Long th32ParentProcessID As Long pcPriClassBase As Long dwFlags As Long szExeFile As String * MAX_PATH End Type Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long Private Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long) ' API Functions to get the processes Private Declare Function Process32First Lib "kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long Function ProcessesRunning(SearchName As String) Dim hSnapShot As Long '* Handle Dim uProcess As PROCESSENTRY32 '* Process Dim lRet '* Return Val Dim processName As String 'On Error Resume Next 'Takes a snapshot of the running processes and the heaps, modules, and threads used by the processes hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&) uProcess.dwSize = Len(uProcess) ProcessesRunning = 0 'Retrieve information about the first process encountered in our system Snapshot lRet = Process32First(hSnapShot, uProcess) Do While lRet lRet = Process32Next(hSnapShot, uProcess) ' Trim the unwanted characters at the end of process processName = Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0)) If InStr(processName, SearchName) Then ProcessesRunning = ProcessesRunning + 1 End If Loop CloseHandle hSnapShot End Function Function SysCADProcessesRunning() SysCADProcessesRunning = ProcessesRunning("SysCAD93.exe") End Function
In python, use the psutil module. http://code.google.com/p/psutil/
from psutil import * def SysCADProcessesRunning(): list of PID numbers associated with SysCAD processes return [i for i in get_pid_list() if Process(i).name=="SysCAD93.exe"]
To kill a load of zombies:
def killSysCADZombies(): for iPID in SysCADProcessesRunning(): terminate(iPID)
There are a lot of other useful functions in this module for querying CPU usage, thread usage, memory etc.