0

I have a bunch of related VB.NET console applications I've written for admin/management functions.

I now want to bring them together under a single Windows Forms application that works as a launcher, but instead of launching the apps as seperate programs, I want to embed the apps in the windows forms app, e.g. have a scrollable list of icons down the left hand side - clicking on one will launch the associated .exe in the right hand pane of the windows forms app.

For now I have a simple single form application with one panel, so I can test out if what I want to do is possible.

Having read around MSDN and SO, I've found other posts about this but none that seem to do what I want.

I don't want to intercept stin/stdout/stderr streams and attempt to emulate the console application, I want to actually run the compiled exe (which I can achieve) but have it run inside the windows form (which I can't achieve, it launches as a seperate process).

The main code for Form1 that I have right now is:

Public Class Form1
Declare Auto Function SetParent Lib "user32.dll" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As Integer
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const WM_SYSCOMMAND As Integer = 274
Private Const SC_MAXIMIZE As Integer = 61488
Dim proc As Process

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    proc = Process.Start("\\fileserver\datashare\path\WIN_MGR.exe")
    proc.WaitForInputIdle()
    SetParent(proc.MainWindowHandle, Me.Panel1.Handle)
    SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
End Sub

End Class

Anyone able to put me in the right direction to actually run the .exe application windowed within the windows form?

Graham Gold
  • 2,435
  • 2
  • 25
  • 34
  • maybe this may help somehow: http://stackoverflow.com/questions/12340329/how-to-embed-a-console-application-inside-a-winforms-application – Mark Zucchini Dec 30 '14 at 14:56
  • I'm afraid those solutions still deal with trying to intercept the stdin/stdout/stderr streams of a seperately running but hidden version of the console application which is what I'm trying to avoid having to do - why try to emulate something that already runs if it can be avoided? (whether or not it can be avoided remains to be seen mind you) – Graham Gold Dec 30 '14 at 15:15
  • http://www.vb-helper.com/howto_net_run_dos.html I don't know will it helpful or not, but if you have a time, you might take a look – Mark Zucchini Dec 30 '14 at 15:27
  • 1
    Your code works for me *if* I replace `proc.WaitForInputIdle()` with just a `Thread.Sleep(1000)`. The `WaitForInputIdle` call fails because the console does not have a graphical interface, but the code seems to need a short pause (waiting for the console handle to be created?). – pmcoltrane Dec 30 '14 at 15:31
  • @pmcoltrane - that works perfectly - if you post as an answer I'll mark it as answer and give you the credit :-) Thanks! – Graham Gold Dec 30 '14 at 15:40
  • 1
    If you don't want a fixed delay you could poll MainWindowHandle in a while loop with a shorter delay until it is not equal to IntPtr.Zero. If the console apps are open to modification then you can set them up to [communicate](http://stackoverflow.com/questions/2740038/how-do-i-wait-until-a-console-application-is-idle) with the "host" app. – Idle_Mind Dec 30 '14 at 15:53
  • @Idle_Mind I'll give that a go - I might add some args into the console application code - if run with no params its a standard run, but with a certain arg set, set this event and also hide the window border and controls (can code a form button that will send the window close when needed - although the console app already has an exit function in it's main menu) – Graham Gold Dec 30 '14 at 16:02

1 Answers1

1

Based on the comments, change your Form_Load as follows:

proc = Process.Start("\\fileserver\datashare\path\WIN_MGR.exe")
Thread.Sleep(1000)  'Possibly replace this with polling MainWindowHandle
SetParent(proc.MainWindowHandle, Me.Panel1.Handle)
SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0)

WaitForInputIdle fails because the console application does not have a graphical interface. For a more accurate delay, Idle_Mind suggests polling MainWindowHandle in a while-loop until it returns a value other than IntPtr.Zero.

Community
  • 1
  • 1
pmcoltrane
  • 3,052
  • 1
  • 24
  • 30