Autor
|
Tema: Abrir ejecutable en un form - ¿Es posible abrir Chrome? (Leído 19,033 veces)
|
NsTeam
Desconectado
Mensajes: 127
|
Tengo el siguiente código que es para abrir un ejecutable en un exe. Option Explicit Private Declare Function GetGUIThreadInfo Lib "user32.dll" ( _ ByVal idThread As Long, _ ByRef pgui As GUITHREADINFO) As Long Private Declare Function SetParent Lib "user32" _ (ByVal hWndChild As Long, _ ByVal hWndNewParent As Long) As Long Private Declare Function GetAncestor Lib "user32.dll" _ (ByVal hwnd As Long, _ ByVal gaFlags As Long) As Long Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" _ (ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As SECURITY_ATTRIBUTES, _ lpThreadAttributes As SECURITY_ATTRIBUTES, _ ByVal bInheritHandles As Boolean, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, ByVal _ lpCurrentDriectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long Private Declare Function SetWindowPos Lib "user32" _ (ByVal hwnd As Long, _ ByVal hWndInsertAfter As Long, _ ByVal x As Long, _ ByVal y As Long, _ ByVal cx As Long, _ ByVal cy As Long, _ ByVal wFlags As Long) As Long Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Type GUITHREADINFO cbSize As Long flags As Long hwndactive As Long hwndFocus As Long hwndCapture As Long hwndMenuOwner As Long hwndMoveSize As Long hwndcaret As Long rcCaret As RECT End Type Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Private Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Boolean End Type Private Const GA_PARENT = 1 Private Const SWP_NOOWNERZORDER = &H200 Private Const SWP_NOZORDER = &H4 Private Const SWP_SHOWWINDOW = &H40 Private udtGUI As GUITHREADINFO Private udtProc As PROCESS_INFORMATION Private Function StartProcess(strProgram As String) As Long Dim udtStartup As STARTUPINFO Dim udtSec As SECURITY_ATTRIBUTES Dim lngReturn As Long udtStartup.cb = Len(udtStartup) udtSec.nLength = Len(udtSec) udtSec.bInheritHandle = True ' ' Start the process ' lngReturn = CreateProcess(strProgram, vbNullString, udtSec, udtSec, _ True, ByVal 0, ByVal 0, vbNullString, _ udtStartup, _ udtProc) txtProcess.Text = Hex(udtProc.dwThreadId) lngReturn = GetAncestor(udtProc.hProcess, GA_PARENT) txtParent.Text = Hex(lngReturn) udtGUI.cbSize = Len(udtGUI) ' ' Wait for an hWnd to be allocated ' Do lngReturn = GetGUIThreadInfo(udtProc.dwThreadId, udtGUI) DoEvents Loop Until udtGUI.hwndactive <> 0 StartProcess = udtGUI.hwndactive End Function Private Sub PositionWindow(hwnd As Long) Dim lngReturn As Long lngReturn = SetWindowPos(hwnd, hwnd, 250&, 0&, 250&, 250&, SWP_NOZORDER Or SWP_SHOWWINDOW) End Sub Private Sub cmdIE_Click() Dim lngReturn As Long Dim strProg As String strProg = "C:\Program Files (x86)\FileZilla FTP Client\filezilla.exe" lngReturn = StartProcess(strProg) End Sub Private Sub Command1_Click() ' ' Change the Parent ' Dim lngReturn As Long Dim lngStyle As Long lngReturn = SetParent(udtGUI.hwndactive, Me.hwnd) Call PositionWindow(udtGUI.hwndactive) lngReturn = GetAncestor(udtGUI.hwndactive, GA_PARENT) txtParent.Text = Hex(lngReturn) End Sub Private Sub Form_Load() txtMe.Text = Hex(Me.hwnd) ' ' Scalemode = Pixel ' Me.ScaleMode = 3 End Sub
Y efectivamente hace lo que yo quiero, abre un programa dentro del formulario, lo probé con la calculadora de Windows e incluso con otros programas Pero lo que no entiendo es por qué no pasa lo mismo con Chrome, me refiero a que lo abre en una nueva ventana mas no dentro del formulario. Me urge terminarlo cuanto antes, espero puedan ayudarme, muchas gracias!
|
|
« Última modificación: 1 Febrero 2015, 00:47 am por NsTeam »
|
En línea
|
|
|
|
engel lex
|
no será porque chrome crea un proceso base y abre un proceso hijo por ventana? tendrías que capturar todos los childs de chrome... si te fijas en el administrador de taréas el siempre abre unas 2 o 3 instancias y luego una por ventana más otras por los flash y "accesorios"
|
|
|
En línea
|
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
|
|
|
NsTeam
Desconectado
Mensajes: 127
|
no será porque chrome crea un proceso base y abre un proceso hijo por ventana? tendrías que capturar todos los childs de chrome... si te fijas en el administrador de taréas el siempre abre unas 2 o 3 instancias y luego una por ventana más otras por los flash y "accesorios"
Hola compañero, gracias por tu respuesta... Es lógico lo que me dices y tienes razón cuando lo vi en el administrador de tareas, pero creer que haya alguna forma de hacerlo modificando el código que tengo, es posible?
|
|
|
En línea
|
|
|
|
engel lex
|
lo siento... solo di una respuesta racional con respecto al problema... pero realmente no se sobre visual basic... esperemos que pase un conocedor de estos temas
|
|
|
En línea
|
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
|
|
|
NsTeam
Desconectado
Mensajes: 127
|
Alguien podría ayudarme, por favor. Aún no puedo dar con la solución
|
|
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
Hola Me resultó interesante tu idea. Así que he estado trabajando un poquillo en el tema. A mi me funciona: - Crea un Picture (que sea un poco grande) - Crea un CommandButton -Intruduce el siguiente código en un form '//Funciones API para incrustar el programa en el picture Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, _ ByVal hWndParent As Long) As Long Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, _ ByVal nCmdShow As Long) As Long Const SHOWMAXIMIZED_eSW = 3& '//Funciones API para obtener el handle de la aplicación que queremos meter en un picture Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long '//Ejecuta el programa Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, _ ByVal lpOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long Const WM_SYSCOMMAND = &H112 Const SC_CLOSE = &HF060& 'ClassName Chrome 'Chrome_RenderWidgetHostHWND <---hijo 'Chrome_WidgetWin_1 <----Padre Private Sub Command1_Click() Dim hwnd As Long ' "C:\Program Files\Google\Chrome\Application\chrome.exe", vbHide 'No sirve ShellExecute Me.hwnd, "Open", "C:\Program Files\Google\Chrome\Application\chrome.exe", _ "www.elhacker.net", "", 1 Espera (5) 'Espera cinco segundos a que se cargue hwnd = FindWindow("Chrome_WidgetWin_1", vbNullString) 'Obtiene el handle padre Call SetParent(hwnd, Picture1.hwnd) 'Meter la apcliación en el picture Call ShowWindow(hwnd, SHOWMAXIMIZED_eSW) 'Lo ajusta al cuadro End Sub Private Sub Espera(Segundos As Single) Dim ComienzoSeg As Single Dim FinSeg As Single ComienzoSeg = Timer FinSeg = ComienzoSeg + Segundos Do While FinSeg > Timer DoEvents If ComienzoSeg > Timer Then FinSeg = FinSeg - 24 * 60 * 60 End If Loop End Sub Private Sub Cerrar_Google(hwnd As Long) If hwnd <> 0 Then Call SetParent(hwnd, 0) ' Libera el programa Call SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, ByVal 0&) 'Cierra el programa hwnd = 0 End If End Sub Private Sub Form_Unload(Cancel As Integer) Dim hwnd As Long hwnd = FindWindow("Chrome_WidgetWin_1", vbNullString) Call Cerrar_Google(hwnd) 'cierra Google End Sub
NOTA IMPORTANTE: Tan sólo hay un problemilla. Cuando le des al botón, Chrome se iniciará pero fuera de form, pasado un par de segundos se introduce en el form. Lo suyo sería iniciarlo en modo hide (oculto) y luego volverlo a hacer visible. Estoy mirando a ver, el shell "programa", vbhide, no funciona. La ventaja que tiene usar ShellExecute es que puedes elegir la URL que quieres que muestre Si usas 64Bits, la dirección del programa debes cambiarla a "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" y bueno ya tu ya sabes, el directorio debe ser el que tu tengas en tu compu o sea Saludos
|
|
« Última modificación: 4 Febrero 2015, 15:40 pm por okik »
|
En línea
|
|
|
|
NsTeam
Desconectado
Mensajes: 127
|
Hola @okik , probé tu código y funciona perfecto. Tengo una duda, ¿Es posible detectar automáticamente la Ruta de Chrome, sin necesidad de que el usuario busque la ruta, en mi caso es "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"?, me preguntaba si hay alguna forma de detectar la ruta de chrome.exe automáticamente.
Muchas gracias nuevamente.
|
|
« Última modificación: 3 Febrero 2015, 22:56 pm por NsTeam »
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
Hola @okik , probé tu código y funciona perfecto. Tengo una duda, ¿Es posible detectar automáticamente la Ruta de Chrome, sin necesidad de que el usuario busque la ruta, en mi caso es "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"?, me preguntaba si hay alguna forma de detectar la ruta de chrome.exe automáticamente.
Muchas gracias nuevamente.
Si claro que se puede. Se me ocurren varias maneras. Pero antes de nada permíteme corregir unas líneas del código que te he dado antes. Hice un copia y pega de mi propio código en Form_Unload y se han colado un par de líneas que no tienen utilidad ahí, se trata de la variable hWndChild que fue un intento de introducir sólamente la Web en el Picture, funcionaba con el Notepad por ejemplo, pero no con Google Chrome. Lo borré en otras partes del código, pero no en el Form_Load, se me pasó. También está lo de Espera(5) que si que es necesario más arriba, porque hay que esperar a que se cargue Google Chrome antes de introducirlo en el Picture, pero para cerrar no hace falta. Private Sub Form_Unload(Cancel As Integer) Dim hwnd As Long Dim hWndChild As Long '<---- BORRAR ESTA LÍNEA 'Espera (5) '<---- BORRAR ESTA LÍNEA hwnd = FindWindow("Chrome_WidgetWin_1", vbNullString) Call Cerrar_Google(hwnd) 'cierra Google End Sub
Debería ser así: Private Sub Form_Unload(Cancel As Integer) Dim hwnd As Long hwnd = FindWindow("Chrome_WidgetWin_1", vbNullString) Call Cerrar_Google(hwnd) 'cierra Google End Sub
En cuanto a lo de - Primera opción: Crear un código de busqueda de Chrome.exe y obtener su directorio (ideal para programas que al actualizarse van cambiando la ubicación) por ejemplo si fuera "\Google\Chrome\Application\ V0014\Chrome.exe" y al actualizarse cambiara a "\Google\Chrome\Application\V 00321\Chrome.exe". Que no es el caso. Te lo digo por si alguna vez te encuentras alguna cosa así. - Segunda opción: Obtener mediante la función Environ el directorio de \program files\ del sistema: Private Sub Command1_Click() Print Environ("programfiles") End Sub
y luego añades el resto "\Google\Chrome\Application\chrome.exe" Print Environ("programfiles") & "\Google\Chrome\Application\chrome.exe"
- Tercera opción: accediendo al registro de windows
|
|
« Última modificación: 4 Febrero 2015, 14:03 pm por okik »
|
En línea
|
|
|
|
Miseryk
Desconectado
Mensajes: 225
SI.NU.SA U.GU.DE (2NE1 - D-Unit)
|
Si claro que se puede. Se me ocurren varias maneras. Pero antes de nada permíteme corregir unas líneas del código que te he dado antes. Hice un copia y pega de mi propio código en Form_Unload y se han colado un par de líneas que no tienen utilidad ahí, se trata de la variable hWndChild que fue un intento de introducir sólamente la Web en el Picture, funcionaba con el Notepad por ejemplo, pero no con Google Chrome. Lo borré en otras partes del código, pero no en el Form_Load, se me pasó. También está lo de Espera(5) que si que es necesario más arriba, porque hay que esperar a que se cargue Google Chrome antes de introducirlo en el Picture, pero para cerrar no hace falta. Private Sub Form_Unload(Cancel As Integer) Dim hwnd As Long Dim hWndChild As Long '<---- BORRAR ESTA LÍNEA 'Espera (5) '<---- BORRAR ESTA LÍNEA hwnd = FindWindow("Chrome_WidgetWin_1", vbNullString) Call Cerrar_Google(hwnd) 'cierra Google End Sub
Debería ser así: Private Sub Form_Unload(Cancel As Integer) Dim hwnd As Long hwnd = FindWindow("Chrome_WidgetWin_1", vbNullString) Call Cerrar_Google(hwnd) 'cierra Google End Sub
En cuanto a lo de - Primera opción: Crear un código de busqueda de Chrome.exe y obtener su directorio (ideal para programas que al actualizarse van cambiando la ubicación) por ejemplo si fuera "\Google\Chrome\Application\ V0014\Chrome.exe" y al actualizarse cambiara a "\Google\Chrome\Application\V 00321\Chrome.exe". Que no es el caso. Te lo digo por si alguna vez te encuentras alguna cosa así. - Segunda opción: Obtener mediante la función Environ el directorio de \program files\ del sistema: Private Sub Command1_Click() Print Environ("programfiles") End Sub
y luego añades el resto "\Google\Chrome\Application\chrome.exe" Print Environ("programfiles") & "\Google\Chrome\Application\chrome.exe"
- Tercera opción: accediendo al registro de windows Sin hardcodear: GetModuleFileName(NULL, EXEFullPath, MAX_PATH);
El NULL es el baseaddress, yo lo llamo desde un hook (DLL) y cuando pasa por una función mia, estoy seguro que es del thread del mismo exe y no de mi thread de la DLL. PD: éso si está en ejecución, de lo contrario es fijarse en el Registro en donde está la lista de todos los programas instalados.
|
|
|
En línea
|
Can you see it? The worst is over The monsters in my head are scared of love Fallen people listen up! It’s never too late to change our luck So, don’t let them steal your light Don’t let them break your stride There is light on the other side And you’ll see all the raindrops falling behind Make it out tonight it’s a revolution
CL!!!
|
|
|
okik
Desconectado
Mensajes: 462
|
Sin hardcodear: GetModuleFileName(NULL, EXEFullPath, MAX_PATH);
El NULL es el baseaddress, yo lo llamo desde un hook (DLL) y cuando pasa por una función mia, estoy seguro que es del thread del mismo exe y no de mi thread de la DLL. PD: éso si está en ejecución, de lo contrario es fijarse en el Registro en donde está la lista de todos los programas instalados. ¿Sin hardcodear? jajaja, ¿Eso está en el diccionario? ¿Qué significa? Es igual, lo supongo "sin hardcodear" otra forma que hay de obtener el /Program files/ del sistema que tenía por ahí guardada y que estaba buscando es esta: Private Sub Command1_Click() Dim X As Variant Dim Y As Variant Set X = CreateObject("Wscript.Shell") Set Y = X.Environment("Process") Print Y("PROGRAMFILES") End Sub
En cuanto a lo que has posteado Miseryk , lo de GetModuleHandle no lo he probado y no se muy bien como va. He probado lo siguiente: Dim hModule%, Buffer$, Length%, Msg$ hModule% = GetModuleHandle("notepad.exe") Buffer$ = Space$(255) Length% = GetModuleFileName(hModule%, Buffer$, Len(Buffer$)) Buffer$ = Left$(Buffer$, Length%) Msg$ = Buffer$ Msgbox Msg$
: Pero me da el directorio de VB6.EXE y no el del notepad.exe en este caso, ni siquiera estando en ejecución. He probado sustituyendo hModule% por el hande de la aplicación (en ejecución). Pero nada, que tampoco. Al usar NULL supongo que tu vas por C++ y no VB, ya que NULL no es válido en VB6, en sustitución sería vbNull
|
|
« Última modificación: 4 Febrero 2015, 15:33 pm por okik »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Abrir nuevo Form C++
.NET (C#, VB.NET, ASP)
|
Lokoo
|
1
|
9,914
|
10 Noviembre 2008, 22:16 pm
por BETA_V
|
|
|
Abrir un form desde otro form con netbeans en java
Java
|
murdock_
|
3
|
47,650
|
1 Enero 2009, 03:44 am
por sapito169
|
|
|
Efecto al abrir el Form
Programación Visual Basic
|
Nardo[N]
|
5
|
7,980
|
10 Febrero 2011, 01:51 am
por Nardo[N]
|
|
|
Abrir ejecutable al abrir una carpeta
Windows
|
Kurolox
|
2
|
4,019
|
15 Julio 2014, 20:54 pm
por Eleкtro
|
|
|
Abrir Chrome dentro de un form
Programación Visual Basic
|
NsTeam
|
4
|
9,000
|
3 Febrero 2015, 13:49 pm
por okik
|
|