在VB.NET MDI Form中打开外部应用程序

时间:2012-01-09 04:31:27

标签: vb.net mdichild external-process

我需要在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,但它不会检查以前的实例。所以每次我点击按钮都会打开一个新的记事本

2 个答案:

答案 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