Link to home
Create AccountLog in
Avatar of WhyDidntItWork
WhyDidntItWork

asked on

VB.Net Process.Start Property

I followed the advice from ID:10963463.  I also read up on msdn's webpage on the process.start overload:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdiagnosticsprocessclassstarttopic3.asp

So I attached the code to a button figuring I can call up the same window if I keep pushing the same button (my objective).  Unfortunately, every time I push the button, I create another instance of notepad (not what I wanted).  Anyways, here's the code:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim p As Process
        p = Process.Start("notepad.exe")
        p.WaitForInputIdle()
    End Sub

Thanks in advance.

WhyDidn'tItWork?
Avatar of kaufmed
kaufmed
Flag of United States of America image

If I understand your requirement correctly, then you would want to do something like below.

Note, I used a lambda function to search for the running proc. If you are using strictly .NET 2.0, then you would need to use a foreach/for loop instead.
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class Form1
    Private _notepadHnd As IntPtr

    <DllImport("user32.dll")> _
    Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean

    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim procs() As Process = Process.GetProcessesByName("notepad")
        Dim runningProc As Process = procs.FirstOrDefault(Function(proc As Process) proc.MainWindowHandle = Me._notepadHnd)

        If Me._notepadHnd = IntPtr.Zero OrElse runningProc Is Nothing Then
            Dim p As Process = Process.Start("notepad.exe")

            Me._notepadHnd = p.MainWindowHandle
        End If

        SetForegroundWindow(Me._notepadHnd)
    End Sub
End Class

Open in new window

Avatar of WhyDidntItWork
WhyDidntItWork

ASKER

Hi.

I should have mentioned that I am using Visual Studios 2010 with Vista operating system.

Nope.  I tried out the code and every time I click the button, I still generate another Notepad instance.  All I want to do is click the button and have that application (notepad - which is already open) set as the active window.

Thanks for trying.
It seems there is some discrepancy between the format of the argument to GetProcessesByName(). Try modifying line 12 to this:
Dim procs() As Process = Process.GetProcesses()

Open in new window

Try:

    FocusApp("notepad")

With:
Private Const SW_SHOWNORMAL As Integer = 1

    Private Declare Function IsIconic Lib "user32" (ByVal handle As Integer) As Integer
    Private Declare Function ShowWindow Lib "user32" (ByVal handle As IntPtr, ByVal nCmdShow As Integer) As Integer
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal handle As IntPtr) As Integer

    Private Sub FocusApp(ByVal ExeName As String)
        Dim processes() As Process = Process.GetProcessesByName(ExeName)
        If processes.Length = 0 Then
            Process.Start(ExeName)
        Else
            ' Restore the window if it is minimized...
            If IsIconic(processes(0).MainWindowHandle) <> 0 Then
                ShowWindow(processes(0).MainWindowHandle, SW_SHOWNORMAL)
            End If

            ' Make it the foreground window...
            SetForegroundWindow(processes(0).MainWindowHandle)
        End If
    End Sub

Open in new window

Nope. Sorry. Neither proposed solutions worked. kaufmed keeps generating multiple instances of the same app. idle mind's suggestion didn't pull up the ap.
Unfortunately, I don't have a Vista machine to test with. The closest I have is Win 7, but that's at the house. I guess that puts me out of the game. It's all up to you now Idle  : )
Hmmm... One more trick up my sleeve  ; )

I forgot to include this in my next-to-previous post. The reason I believe my code is "failing" on your machine (and mine at one point) is because the code launching notepad is getting past the Me._notepadHnd = p.MainWindowHandle line prior to the actual WindowHandle being created, which means that the line:
If Me._notepadHnd = IntPtr.Zero OrElse runningProc Is Nothing Then

Open in new window


will succeed on the first condition because the line:
Me._notepadHnd = p.MainWindowHandle

Open in new window


is assigning a value of zero, due to the handle not being available yet--of course, I could be talking out of my rear here. The mod I had implemented (but forgot to include in the post), was to wait for the input to be idle, via WaitForInputIdle(). The reason why I believe this works is that this method is dependent on a message loop in the target process, and if you've got a message loop, then you should have a window handle.

One last try. Here is the complete code I was running for my previous post. If this isn't it, then I'm tapping out  : )
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class Form1
    Private _notepadHnd As IntPtr

    <DllImport("user32.dll")> _
    Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim procs() As Process = Process.GetProcesses()
        Dim runningProc As Process = procs.FirstOrDefault(Function(proc As Process) proc.MainWindowHandle = Me._notepadHnd)

        If Me._notepadHnd = IntPtr.Zero OrElse runningProc Is Nothing Then
            Dim p As Process = Process.Start("notepad.exe")

            p.WaitForInputIdle(-1)
            Me._notepadHnd = p.MainWindowHandle
        End If

        SetForegroundWindow(Me._notepadHnd)
    End Sub
End Class

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
It worked.  Thanks Idle Mind.