Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Declarar funciones en VB Script

160 views
Skip to first unread message

Pablo Gutierrez

unread,
Jul 6, 2004, 11:56:47 AM7/6/04
to
Hola a todos, Tengo una duda de novato de VB Script.
Desconozco si es posible declarar funciones en VBS como:

Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long

Cuando lo ejecuto me da un error de sintaxis en esta línea.

EN VB6 no da problemas... ¿se han de declarar de alguna
forma especial o no es posible en VB Script?

Leonardo Azpurua arroba punto

unread,
Jul 6, 2004, 12:23:49 PM7/6/04
to

"Pablo Gutierrez" <anon...@discussions.microsoft.com> escribió en el
mensaje news:27fd001c46371$d7f04ac0$a301...@phx.gbl...

Hola a todos, Tengo una duda de novato de VB Script.
Desconozco si es posible declarar funciones en VBS como:

Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long

Cuando lo ejecuto me da un error de sintaxis en esta línea.

---------------------------------

Hola, Pablo:

En VBScript no tienes la instrucción Declare, ni se especifica el tipo de
las variables.

Si quieres llamar a una función de un API, debes "encapsularla" en una clase
de una DLL, e instanciarla mediante CreateObject desde el script.

Tomando como ejemplo tu caso particular:

Creas un proyecto, llamémoslo ApiLib.prj. Agregas una clase, que tambien
puedes llamar ApiLib(.cls).

En ApiLib.cls declaras:

Private Declare Function libOpenProcess Lib "kernel32" Alias "OpenProcess" _


(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _

ByVal dwProcessId As Long) As Long (*)

Public Function OpenProcess(DesiredAccess, InheritHandle, ProcessID) As Long
Dim p1 As Long, p2 As Long, p3 As Long (**)
p1 = DesiredAccess
p2 = InheritHandle
p3 = ProcessID
OpenProcess = libOpenProcess(p1, p2, p3)
End Function

Generas la DLL (trata de evitar guardarla en Windows\System, o su
equivalente).

Luego, ya en el script, escribes:

Dim LibApi

Set LibApi = CreateObject("ApiLIb.ApiLib")
r = LibApi.OpenProcess(Acceso, HeredaHandle, idProceso)

Está de más decir que puedes ir expandiendo la DLL según vayas necesitando
nuevas funciones de Api en tus scripts.


------------------------------
NOTAS:
* El uso del Alias en el Declare te permite utilizar un nombre diferente
del original para la función. De esta manera, el nombre original queda
disponible para identificar la función a exportar.
** Los parámetros de la función exportada son definidos (implícitamente) As
Variant. Esto es requerido por VBScript cuando se trata de parámetros por
referencia. Es decir, en este caso podían haberse declarado As Long, y era
prescindible el uso de las variables temporales (p1, p2, p3). Las incluí
como ilustración de una técnica que puede resultar imprescindible: no está
de más convertirlo en un estándar.


--
Salud!

Leonardo
[MVP Visual Basic]
leonardo<arroba>mvps<punto>org

"El presente es una luz que palpita entre dos tinieblas"
- Naguib Mahfuz


Alexander Osorio

unread,
Jul 6, 2004, 12:28:01 PM7/6/04
to
Hasta donde se, no se puede

"Pablo Gutierrez" <anon...@discussions.microsoft.com> escribió en el
mensaje news:27fd001c46371$d7f04ac0$a301...@phx.gbl...

Hola a todos, Tengo una duda de novato de VB Script.
Desconozco si es posible declarar funciones en VBS como:

Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long

Cuando lo ejecuto me da un error de sintaxis en esta línea.

EN VB6 no da problemas... żse han de declarar de alguna

Rubén Vigón

unread,
Jul 6, 2004, 12:32:10 PM7/6/04
to
No es posible utilizar APIs en VBScript (en VBScript sólo existe el tipo de datos «Variant», mientras que las APIs de Win32 usan tipos de datos "estrictos"); pero la solución es bastante sencilla: sólo tienes que hacer un envoltorio en Visual Basic y utilizarlo desde tu VBScript (mediante «CreateObject»)

Un saludo!

Rubén Vigón
Microsoft MVP Visual Basic
http://www.mvp-access.com/rubenvigon

Pablo

unread,
Jul 7, 2004, 4:55:25 AM7/7/04
to
Ante todo muchas gracias a todos y en especial a ti
Leonardo, todo un experto en VB!!

El motivo de la consulta era crear un script, para detener
la ejecución del código que va a continuación de un SHELL.
Ya que se me empiezan a abrir inputbox antes de que se
ejecute la instrucción del Shell.

En VB6 no hay problemas con GetExitCodeProcess. El código
en VB es éste, pero en VBS da el error de sintaxis con el
que me encontraba.

Private Const WAIT_INFINITE = -1&
Private Const SYNCHRONIZE = &H100000

Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long

Private Declare Function WaitForSingleObject
Lib "kernel32" _
(ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long

Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long


Private Sub Command1_Click()

Dim hProcess As Long
Dim taskId As Long
Dim cmdline As String

cmdline = "notepad.exe"
taskId = Shell(cmdline, vbNormalFocus)

hProcess = OpenProcess(SYNCHRONIZE, True, taskId)
Call WaitForSingleObject(hProcess, WAIT_INFINITE)
CloseHandle hProcess

MsgBox "La aplicación Shell ha finalizado."

End Sub

¿hay mucha diferencia en VB Script?¿Cámo se encapsularia?
Gracias.

>-----Mensaje original-----

>.
>

Leonardo Azpurua arroba punto

unread,
Jul 7, 2004, 8:15:59 AM7/7/04
to

"Pablo" <anon...@discussions.microsoft.com> escribió en el mensaje
news:2891401c46400$24d14a90$a301...@phx.gbl...

> El motivo de la consulta era crear un script, para detener
> la ejecución del código que va a continuación de un SHELL.
> Ya que se me empiezan a abrir inputbox antes de que se
> ejecute la instrucción del Shell.
>
> En VB6 no hay problemas con GetExitCodeProcess. El código
> en VB es éste, pero en VBS da el error de sintaxis con el
> que me encontraba.
> ... (código omitido)

> ¿hay mucha diferencia en VB Script?¿Cámo se encapsularia?
> Gracias.

Hola, Pablo:

"Encapsular", en el caso de las llamadas a funciones de API, equivale a
"envolverlas" en una clase y "mostrarlas" a través de un método de esa clase
para hacerla reutilizable en futuros proyectos, o -como es el caso actual-
"digerible" a otros entornos.

En mi respuesta anterior te di un ejemplo paso por paso de como encapsular
una llamada al API (OpenProcess). Aquí se podría hacer otro tanto.

- Inicias un proyecto tipo DLL (si no leiste algo acerca de las DLL hasta
ahora, comienza a hacerlo cuanto antes), podrías llamarlo ApiLib.prj, igual
que ayer, o como mejor te parezca: elige un nombre que te sirva, porque vas
a usarla muy seguido.

Creas una clase (puedes llamarla CExecuteWait, por ejemplo)

Insertas tus definiciones de constantes y declares (las omito de la
respuesta).

Ahora nos concentramos en esta función, que es el nucleo de CExecuteWait

Public Sub ExecWait(cmdLine)


Dim hProcess As Long
Dim taskId As Long

taskId = Shell(cmdline, vbNormalFocus)

hProcess = OpenProcess(SYNCHRONIZE, True, taskId)
Call WaitForSingleObject(hProcess, WAIT_INFINITE)
CloseHandle hProcess

End Sub

tu "Button1_Click", con un cambio de nombre y dos pequeños ajustes se
convirtió en la sub ExecWait, que recibe como parámetro el nombre del
programa a ejecutar, lo inicia y espera a que termine.

Y desde el script escribes:

Dim objExec
Set objExec = CreateObject("ApiLib.CExecuteWait")
objExec.ExecWait "notepad.exe"
msgBox "La aplicación terminó"

Y el principio general es el siguiente:

Cuando desde VBS queremos ejecutar algo que éste no permite, pero VB sí, lo
implementamos en VB, lo metemos en una clase, y creamos un método que
implemente la funcionalidad deseada.

0 new messages