我需要在VB.NET MDI表单中打开一些外部应用程序,例如notepad.exe,而且我还需要确保始终只有一个这样的副本。
我使用下面的代码,但它完全没有任何意义。它给出了错误,未声明SetParent,并且未声明findWindow
Dim myProcess As Process = New Process()
Dim MyHandle As IntPtr
myProcess.StartInfo.FileName = "Notepad.exe"
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.Start()
MyHandle = FindWindow(vbNullString, "C:\Windows\Notepad.exe")
SetParent(MyHandle, Me.Handle)
myProcess.WaitForExit()
这是我用来验证只有一个实例正在运行的代码
If (System.Diagnostics.Process.GetProcesses.Equals("notepad.exe")) Then
MsgBox("Only One Instance!")
Else
Dim p As New System.Diagnostics.Process
p.StartInfo.FileName = "notepad.exe"
p.Start()
End If
此代码正在打开notepad.exe,但它不会检查以前的实例。所以每次我点击按钮都会打开一个新的记事本
答案 0 :(得分:4)
必须先声明SetParent和FindWindow才能使用它们,这就是您收到错误的原因。您在查找记事本的现有实例时遇到问题,因为GetProcesses返回集合,而不是单个进程。要使用您正在尝试的方法,您需要遍历整个集合以查看它是否包含匹配项或使用.Contains。我没有在我的例子中使用FindWindow,但如果你将来需要它,我已经包含了它的声明。示例代码假定要使用的表单名为Form1,并且使用Button1激活代码。
代码:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("User32", CharSet:=CharSet.Auto, ExactSpelling:=True)> Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndParent As IntPtr) As IntPtr
End Function
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim PROCHANDLE As System.IntPtr = -1
For Each proc In Process.GetProcesses
If LCase(proc.ProcessName) = "notepad" Then
PROCHANDLE = proc.Handle
End If
Next
If PROCHANDLE = -1 Then
PROCHANDLE = Process.Start("C:\windows\notepad.exe").Handle
SetParent(PROCHANDLE, Me.Handle)
End If
End Sub
End Class
答案 1 :(得分:0)
这很有效,我只是尝试过。 只需创建一个新的Windows窗体项目并粘贴此代码代替form1默认代码
即可 Public Class Form1
Dim myProcess As Process = New Process()
Public WithEvents thb As Button = New System.Windows.Forms.Button
Public Declare Function SetParent Lib "user32" Alias "SetParent" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As System.IntPtr
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles thb.Click
myProcess.Start()
myProcess.WaitForInputIdle()
SetParent(myProcess.MainWindowHandle, Me.Handle)
thb.Text = "Open Notepad Again"
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
WindowState = FormWindowState.Maximized
MaximizeBox = False
ShowIcon = False
Text = "Notepad Opener"
thb.Location = New System.Drawing.Point(20, 20)
thb.Name = "thb"
thb.Size = New System.Drawing.Size(200, 23)
thb.TabIndex = 1
thb.Text = "Open Notepad"
thb.UseVisualStyleBackColor = True
Controls.Add(Me.thb)
IsMdiContainer = True
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.StartInfo.FileName = "notepad.exe"
End Sub
End Class