Opening external application inside VB.NET MDI Form

Yoosuf picture Yoosuf · Jan 9, 2012 · Viewed 11k times · Source

I need to open some external applications such as notepad.exe inside the VB.NET MDI form, and also I need to make sure that there is exactly only one copy of this running always.

I used the code below, but it does absolutely nothing at all. It gives the error 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()

This is the code I used to verify that only one instance is running

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 

This code is opening notepad.exe but it is NOT checking for previous instances. So everytime I click the button it opens a new Notepad

Answer

Aaron Smith picture Aaron Smith · May 31, 2012

SetParent and FindWindow must be declared before you can use them, that is why you are receiving the error. You are also having an issue finding the existing instance of Notepad because GetProcesses returns a collection, not an individual process. To use the method you are trying, you would need to loop through the entire collection to see if it contains a match or use .Contains. I didn't use FindWindow in my example, but I have included the declaration for it if you need it in the future. The example code assumes that the form to be used is entitled Form1 and that the code is activated with Button1.

Code:

    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