我希望在连接到应用程序中的对象之前检测SolidWorks.exe的隐藏实例。原因是SolidWorks有时会意外关闭,但仍然在后台进程中打开,如任务管理器所示。因此,当我的应用程序启动时,我想连接到一个可见实例或创建一个新实例,确保不存在任何隐藏实例。
如何杀死隐藏的实例?
Dim procs() As Process = Process.GetProcessesByName("SLDWORKS")
For Each proc As Process In procs
'.hidden is not a real property for proc, but for questioning only
if proc.hidden = true Then
proc.kill()
End If
Next
答案 0 :(得分:0)
您可以获取进程的窗口状态,并使用它来确定用户当前是否可以看到它,如此StackOverflow问题中所述:
Get window state of another process
这将涉及使用P / Invoke(非托管代码),仅供参考。
为方便起见,这里的答案与转换为VB的答案相同:
Shared Sub Main(args() As String)
Dim procs() As Process = Process.GetProcesses()
For Each proc As Process In procs
If proc.ProcessName = "notepad" Then
Dim placement = GetPlacement(proc.MainWindowHandle)
MessageBox.Show(placement.showCmd.ToString())
End If
Next
End Sub
Private Shared Function GetPlacement(hwnd As IntPtr) As WINDOWPLACEMENT
Dim placement As WINDOWPLACEMENT = New WINDOWPLACEMENT()
placement.length = Marshal.SizeOf(placement)
GetWindowPlacement(hwnd, placement)
Return placement
End Function
<DllImport("user32.dll", SetLastError:=True)>
Friend Shared Function GetWindowPlacement(ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<Serializable>
<StructLayout(LayoutKind.Sequential)>
Friend Structure WINDOWPLACEMENT
Public length As Integer
Public flags As Integer
Public showCmd As ShowWindowCommands
Public ptMinPosition As System.Drawing.Point
Public ptMaxPosition As System.Drawing.Point
Public rcNormalPosition As System.Drawing.Rectangle
End Structure
Friend Enum ShowWindowCommands As Integer
Hide = 0
Normal = 1
Minimized = 2
Maximized = 3
End Enum
<小时/> 如果窗口确实在&#34;正常&#34;窗口状态,那么也许它的位置不是你有权访问的位置。尝试使用此代码显示窗口的位置。
Dim procs() As Process = Process.GetProcesses()
For Each proc As Process In procs
If proc.ProcessName = "notepad" Then
Dim placement = GetPlacement(proc.MainWindowHandle)
MessageBox.Show(placement.showCmd.ToString())
Dim windowRect As Rectangle = New Rectangle()
GetWindowRect(proc.MainWindowHandle, windowRect)
MessageBox.Show(windowRect.Top.ToString() + " | " + windowRect.Left.ToString() + " | " + windowRect.Bottom.ToString() + " | " + windowRect.Right.ToString())
End If
Next
这里是GetWindowRect
<DllImport("user32.dll", SetLastError:=True)> _
Friend Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lprect As Rectangle) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<小时/> 由于窗口边框是非传统的,让我们试试这个人:
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Friend Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
End Function
答案 1 :(得分:0)
这是我最终创建的解决方案,可以满足我们的需求。 您可以使用任务管理器验证结果。
VB版
Public Function ConnectToSolidWorks() As sldworks.SldWorks
Dim sw As sldworks.SldWorks = Nothing
Dim ProcessID As Integer = 0
'GetObject
'Will only attach to an active solidworks session in the (Apps)
'Will NOT attach to solidworks session in (Background processes)
Try
sw = GetObject(, "SldWorks.Application")
If sw IsNot Nothing Then
If sw.Visible = False Then sw.Visible = True
ProcessID = sw.GetProcessID
End If
Catch ex As Exception
End Try
'Kill any other session of solidworks other than the active session
'by comparing the ProcessID's
Dim procs() As Process = Process.GetProcessesByName("SLDWORKS")
For Each proc As Process In procs
If proc.Id <> ProcessID Then
proc.Kill()
End If
Next
'CreateObject
'If GetObject did not attach to an active session of solidworks then
'create a brand new instance of solidworks session
If sw Is Nothing Then
sw = CreateObject("SldWorks.Application")
If sw IsNot Nothing Then
If sw.Visible = False Then sw.Visible = True
End If
End If
Return sw
End Function
C#版
public sldworks.SldWorks ConnectToSolidWorks()
{ sldworks.SldWorks sw = null; int ProcessID = 0;
//GetObject
//Will only attach to an active solidworks session in the (Apps)
//Will NOT attach to solidworks session in (Background processes)
try {
sw = Interaction.GetObject(, "SldWorks.Application");
if (sw != null) {
if (sw.Visible == false)
sw.Visible = true;
ProcessID = sw.GetProcessID;
}
} catch (Exception ex) {
}
//Kill any other session of solidworks other than the active session
//by comparing the ProcessID's
Process[] procs = Process.GetProcessesByName("SLDWORKS");
foreach (Process proc in procs) {
if (proc.Id != ProcessID) {
proc.Kill();
}
}
//CreateObject
//If GetObject did not attach to an active session of solidworks then
//create a brand new instance of solidworks session
if (sw == null) {
sw = Interaction.CreateObject("SldWorks.Application");
if (sw != null) {
if (sw.Visible == false)
sw.Visible = true;
}
}
return sw;
}