Открытие внешнего приложения внутри VB.NET MDI Form
Мне нужно открыть некоторые внешние приложения, такие как notepad.exe внутри формы VB.NET MDI, а также мне нужно убедиться, что всегда есть только одна копия этого запущенного приложения.
Я использовал приведенный ниже код, но он абсолютно ничего не делает. Это дает ошибку 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 ответа
SetParent и FindWindow должны быть объявлены до того, как вы сможете их использовать, поэтому вы получаете сообщение об ошибке. У вас также есть проблема с поиском существующего экземпляра Notepad, потому что GetProcesses возвращает коллекцию, а не отдельный процесс. Чтобы использовать метод, который вы пытаетесь, вам нужно было бы перебрать всю коллекцию, чтобы увидеть, содержит ли она совпадение или использовать.Contains. Я не использовал FindWindow в моем примере, но я включил объявление для него, если оно понадобится вам в будущем. В примере кода предполагается, что используемая форма называется "Форма 1" и что код активируется с помощью кнопки "1".
Код:
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
Это работает очень хорошо, я только что попробовал. Достаточно создать новый проект Windows Forms и вставить этот код вместо кода по умолчанию в форме 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