1

我需要在 VB.NET MDI 窗体中打开一些外部应用程序,例如 notepad.exe,并且我需要确保始终只有一个副本在运行。

我使用了下面的代码,但它完全没有任何作用。它给出了错误 SetParent is not declared and findWindow is not declared

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

4

2 回答 2

5

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
于 2012-05-31T14:50:51.410 回答
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

于 2016-10-16T21:44:07.660 回答