[RESOLVED] Running another application inside a picturebox - issue with Windows7 permission
Hi guys,
This is the sample code that I used to run another application inside a picturebox:
Code:
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll")> Public Shared Function SetParent(ByVal hwndChild As IntPtr, ByVal hwndNewParent As IntPtr) As Integer
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Process1 As New Process
Process1.StartInfo.FileName = "notepad.exe"
Process1.Start()
Do Until Process1.WaitForInputIdle = True
Application.DoEvents()
Loop
SetParent(Process1.MainWindowHandle, PictureBox1.Handle)
End Sub
End Class
Thus, I was able to host another application inside my VB2010 WindowsForm and it works fine. But the problem is, in Windows7, Windows would ask for the permission(whether you want to allow the EXE to run or not). After clicking the "Allow" button, the exe application would open on it's own window rather than as a child of the PictureBox
I think when Windows asks for the permission, it is skipping the SetParent() API call. I really appreciate any suggestions or corrections or recommendations.
Thanks in advance :)
:wave:
Re: Running another application inside a picturebox - issue with Windows7 permission
Hi
I would be keen also on this as I tried while back with similar problems.
VbAzza
Re: Running another application inside a picturebox - issue with Windows7 permission
try....
When coding start VS as admin.
For compile, set requestedExecutionLevel line in app.manifest to level="requireAdministrator".
Code:
' When coding start VS as admin.
' For compile, set requestedExecutionLevel line in app.manifest to level="requireAdministrator".
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll")>
Private Shared Function SetParent(ByVal hwndChild As IntPtr _
, ByVal hwndNewParent As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function IsWindow(ByVal hWnd As IntPtr) As Boolean
End Function
' variables used to restore launched app
Private origOwner As IntPtr = IntPtr.Zero
Private app_hWnd As IntPtr = IntPtr.Zero
' launch app, change parent to Me.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim p As New Process
p.StartInfo.FileName = "regedit.exe"
p.Start()
p.WaitForInputIdle(-1)
' wait upto 5 secs to get MainWindowHandle (not zero).
For i = 1 To 50
If Not p.MainWindowHandle = IntPtr.Zero Then
Exit For
End If
Threading.Thread.Sleep(100)
Next
If p.MainWindowHandle = IntPtr.Zero Then
MessageBox.Show("Unable to get window handle")
Else
' demo limited to one instance, so disable this button!
Button1.Enabled = False
' save handle
app_hWnd = p.MainWindowHandle
' save current parent/set new parent as Me.
origOwner = SetParent(app_hWnd, Me.Handle)
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
' restore app to original parent (if still running).
If Not app_hWnd = IntPtr.Zero Then
If IsWindow(app_hWnd) Then
SetParent(app_hWnd, origOwner)
End If
End If
End Sub
End Class
Re: Running another application inside a picturebox - issue with Windows7 permission
Thanks Edge :wave:
Will let you know after testing it... :)
Re: Running another application inside a picturebox - issue with Windows7 permission
Quote:
Originally Posted by
akhileshbc
Thanks Edge :wave:
Will let you know after testing it... :)
Was just thinking, instead of using IsWindow API, maybe better to have the process in scope and use it instead?
Code:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll")>
Private Shared Function SetParent(ByVal hwndChild As IntPtr, ByVal hwndNewParent As IntPtr) As IntPtr
End Function
' variables used for launched app
Private originalParent As IntPtr = IntPtr.Zero
Private app_process As New Process
' launch app, change parent to Me.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
app_process.StartInfo.FileName = "regedit.exe"
app_process.Start()
app_process.WaitForInputIdle(-1)
' wait upto 5 secs to get MainWindowHandle (not zero).
For i = 1 To 50
If Not app_process.MainWindowHandle = IntPtr.Zero Then
Exit For
End If
Threading.Thread.Sleep(100)
Next
If app_process.MainWindowHandle = IntPtr.Zero Then
MessageBox.Show("Unable to get window handle")
Else
Button1.Enabled = False ' demo limited to one instance, so disable this button!
' save current parent/set new parent as Me.
originalParent = SetParent(app_process.MainWindowHandle, Me.Handle)
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
' restore app to original parent (if still running).
If (app_process.HasExited) = False Then
SetParent(app_process.MainWindowHandle, originalParent)
End If
End Sub
End Class
Re: Running another application inside a picturebox - issue with Windows7 permission
Thanks Edge... that worked.. :wave:
Re: [RESOLVED] Running another application inside a picturebox - issue with Windows7
Edge, I have a small issue related to this. I am using SetWindowPos API to set the window of the external application to fit in top-left position and the width&height of the picturebox.
Code used:
Code:
'...
originalParentFlashDump = SetParent(processFlashDump.MainWindowHandle, picFlashDumpProcess.Handle)
Const SWP_SHOWWINDOW = &H40
SetWindowPos(processFlashDump.MainWindowHandle, 0, 0, 0, picFlashDumpProcess.Width, picFlashDumpProcess.Height, SWP_SHOWWINDOW)
'....
The problem is, if this embedded application has some modal dialog boxes(when a button is clicked, it opens a modal dialog), it gets detached from the picturebox.
When I commented out the SetWindowPos function call, it is working fine. So, I believe, it is something with the flags to be set.
I tried reading the manual of this API. And I tried some of the flags (tried ORing some of them). But was not successful. Do you have any suggestions for this ?
Thanks :wave:
Re: [RESOLVED] Running another application inside a picturebox - issue with Windows7
Quote:
Originally Posted by
akhileshbc
Edge, I have a small issue related to this. I am using SetWindowPos API to set the window of the external application to fit in top-left position and the width&height of the picturebox.
I doubt that API is the cause.
SetParent says,.. if hWndNewParent is not NULL and the window was previously a child of the desktop, you should clear the WS_POPUP style and set the WS_CHILD style before calling SetParent.
note, WS_CHILD says,.. A window with this style cannot have a menu bar.
With that info I did a quick test using the code in post #5 and sure enough RegEdit no longer shows a menu bar, but I could still use "Control+F" keys to bring up the Find dialog and the regedit dialogs were now owned by my form instead of the desktop, so I guess thats a start? Other then that I'm not sure what the real solution would be or really how to set window styles , mostly guessing here...
Code:
' change window style
Dim style As Integer = GetWindowLong(app_process.MainWindowHandle, WindowLongFlags.GWL_STYLE)
style = CInt((style And Not (WS_POPUP)) Or WS_CHILD)
SetWindowLong(app_process.MainWindowHandle, WindowLongFlags.GWL_STYLE, CType(style, IntPtr))
' save current parent/set new parent as Me.
originalParent = SetParent(app_process.MainWindowHandle, Me.Handle)
WindowLong declares,
http://www.pinvoke.net/default.aspx/...indowLong.html
http://www.pinvoke.net/default.aspx/...indowLong.html
http://www.pinvoke.net/default.aspx/...LongFlags.html
Re: [RESOLVED] Running another application inside a picturebox - issue with Windows7
Thanks :wave:
I'll try that :thumb:
Re: [RESOLVED] Running another application inside a picturebox - issue with Windows7
[QUOTE=akhileshbc;4218271]Hi guys,
This is the sample code that I used to run another application inside a picturebox:
Code:
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll")> Public Shared Function SetParent(ByVal hwndChild As IntPtr, ByVal hwndNewParent As IntPtr) As Integer
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Process1 As New Process
Process1.StartInfo.FileName = "notepad.exe"
Process1.Start()
Do Until Process1.WaitForInputIdle = True
Application.DoEvents()
Loop
SetParent(Process1.MainWindowHandle, PictureBox1.Handle)
End Sub
End Class
Sir, I have used this code of yours in my program but i have errors of "WaitForInputIdle failed. This could be because the process does not have a graphical interface." I had replace the "notepad.exe" to my own exe file and my exe file is from visual studio C++ i had made. what could be the Error means sir?
here's the error code appeared:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRed.Click
Dim RetVal As New Process()
'--buttons enable / disable--
btnSave.Enabled = True
btnRed.Enabled = False
btnStop.Enabled = True
'--This is to eliminate the cmd prompt box that used to pop up same time with the CV executable file--
RetVal.StartInfo.UseShellExecute = False
RetVal.StartInfo.FileName = "C:\Special Prob\HSV Detection Red\Debug\camera.exe"
RetVal.StartInfo.CreateNoWindow = True
RetVal.Start()
'here's you code appear
Do Until RetVal.WaitForInputIdle = True
Application.DoEvents()
Loop
SetParent(RetVal.MainWindowTitle, PictureBox1.Handle)
stopPreviewCamera()
End Sub
Kindly lecture me some of your knowledge sir...
Re: [RESOLVED] Running another application inside a picturebox - issue with Windows7
Quote:
Originally Posted by
chummycastro
Hi guys,
This is the sample code that I used to run another application inside a picturebox:
Kindly lecture me some of your knowledge sir...
Right, you can't use WaitForInputIdle on windows that don't have a message loop, throws an error.
Using code in post #5 I tested with a console app I made in VB and got it to work, but the console window wasn't hidden, so I used the ShowWindow API to do that.
Code:
' launch app, change parent to Me.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
app_process.StartInfo.FileName = "M:\ConsoleApplication1\bin\Release\ConsoleApplication1.exe"
app_process.StartInfo.CreateNoWindow = True ' < had no effect on console app.
app_process.Start()
' wait upto 3 secs to get handle
For i = 1 To 300
If Not app_process.MainWindowHandle = IntPtr.Zero Then
Exit For
End If
Threading.Thread.Sleep(10)
app_process.Refresh()
Next
If app_process.MainWindowHandle = IntPtr.Zero Then
MessageBox.Show("Unable to get handle")
Else
' hide the window.
ShowWindow(app_process.MainWindowHandle, ShowWindowCommands.SW_HIDE)
' save current parent/set new parent as Me.
originalParent = SetParent(app_process.MainWindowHandle, Me.Handle)
' disable this button
Button1.Enabled = False
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
' restore app to original parent (if still running).
If (app_process.HasExited) = False Then
' restore to original parent
SetParent(app_process.MainWindowHandle, originalParent)
' unhide the window.
ShowWindow(app_process.MainWindowHandle, ShowWindowCommands.SW_SHOW)
End If
End Sub