Hola a todos.
Espero que hayáis tenido unas buenas vacaciones LifeIfSoft.
Ya veo que se ha animado algo el foro y por eso quiero aportar algo en este comienzo de curso.
Seguro que alguna vez habéis tenido la necesidad de evitar que el Usuario arranque más de una vez la Aplicación Velneo y como no he encontrado nada en el foro, os cuento mi experiencia (solo válido para Windows).
El problema a resolver es el siguiente:
El Usuario dispone en el escritorio de un acceso directo (.lnk) apuntando a vClient.exe y con el parámetro de la ruta VATP correspondiente.
El Usuario arranca el acceso directo y minimiza la aplicación en la barra de Tareas.
El Usuario arranca de nuevo el acceso directo y en este caso la ventana de la Aplicación debe mostrarse en pantalla restaurando su posición y tamaño anteriores.
He contemplado 3 formas de controlar la Multi Instanciación de una Aplicación en la misma máquina.
1º - Tenemos una variable global en 3º plano APP_INSTANCIAS en la que en el PRE del Autoexec iremos guardando las máquinas que van haciendo conexión en el vServer. La información a guardar puede ser APP_SIGLAS + getClientIP(). En el PRE del autoexec comprobamos si existe APP_SIGLAS + getClientIP() en APP_INSTANCIAS y en caso afirmativo devolvemos 0 para salir de la Aplicación. En el OnClose de la Aplicación elimino la información en APP_INSTANCIAS.
Para activar la ventana de la Aplicación que está minimizada he recurrido a las DLL’s del API Win32 pero con Velneo y su pésima gestión de DLL’s he sido incapaz.
2º - La 1º opción tiene el problema de que si vClient se cierra anormalmente la variable global APP_INSTANCIAS en 3P quedaría con un valor inconsistente. Así que visto mi fracaso con la gestión de DLL’s de Velneo recurrí a una herramienta de Script que contemplara funciones de acceso al API de Windows. Dicha herramienta se llama AutoIt3 (https://www.autoitscript.com/site/autoit/). Solo tenemos que adjuntar el Runtime Autoit3.exe a nuestra aplicación y podremos ejecutar macros con mucha mayor potencia que con VBScript.
Para comprobar si la Aplicación ya está instanciada y activar la ventana, creamos un fichero activarventana.au3 con el siguiente código:
; Comprueba que existe la ventana y la Activa
if WinExists ( TITULO ) then
WinActivate ( TITULO )
else
; Devuelve 1 para indicar error
exit (1)
endif
TITULO es el título de la Ventana principal de nuestra Aplicación.
Usamos en el PRE del autoexec un proceso PRO_MULTI_SETUP que preguntará si nuestra Aplicación admite Multiinstanciación. Si la respuesta es negativa ejecutará la macro (sysCacheClientPath/AutoIt3.exe activarventana.au3) para probar si puede activar una ventana de la Aplicación instanciada. Si la macro tiene éxito cerramos la instancia actual (PRO_MULTI_SETUP retorna 0). Si la macro devuelve Error la ejecución del autoexec sigue normalmente.
3º - La 2º opción tiene una pequeña pega. Para comprobar la multi instanciación el usuario debe pasar siempre por el proceso de Login. Así que recurrimos a la 3º opción que consiste en comprobar si la Aplicación está activa antes de ejecutar vClient.exe.
Usamos también AutoIt3 (en este caso un exe con la macro compilada). Disponemos en una carpeta de lo siguiente:
1- El Script lanzador_velneo.au3 que compilamos como _lanzador_velneo.exe
2- Los accesos directos .LNK de nuestras Aplicaciones que ejecutan vClient.exe con el VATP de conexión
El ejecutable lanzador_velneo.exe recibe como parámetro el nombre del acceso directo .lnk (ejem: lanzador_velneo.exe 0PS_APP_2). Comprueba si la Aplicación está en ejecución. Si es así activa la ventana de la Aplicación y en caso contrario usa la función SHELLEXECUTE() para ejecutar el fichero .lnk pasado como parámetro.
Adjunto un ejemplo de lanzador_velneo.au3 que muestra esta técnica.
Este sistema es el que mejor resultados ha obtenido: disponemos de los accesos directos lnk originales y además las aplicaciones se instancian en la Barra de Tareas de forma independiente sin combinar los botones cuando esta opción está activada en Win7 o Win8.
Me imagino que esta cuestión de la Multi Instanciación la habréis resuelto de diversas formas y me gustaría conocer vuestras opciones.
Sí, por supuesto, ya había pensado en esa posibilidad. Incluso estuve mirando la raquítica documentación que hay al respecto y obtuve algunas conclusiones positivas, véase http://velneo.es/foros/topic/cliente-offline-qml.
La verdad es que sin un buen editor/depurador de QML y mis nulos conocimientso de Qt/C++ prefiero esperar a que Velneo se ponga las pilas en este y otros temas. De momento soy más productivo con AutoIt3.
¡¡ Qué más quisiera yo que hubiera ya cientos de componentes QML en el mercado compatibles con Velneo !!
Para un experto en QML seguro que resolver este problema es muy sencillo. A ver si alguien se anima.
Me he encontrado este hilo, tratando de buscar una solución a la disponibilidad de conexiones al servidor en una red, para que un solo equipo solo consuma una, me he declinado por la opción 3 sugerida en tu ejemplo, pero Windows me dice que no encuentra el archivo .lnk, pero autoit si valida su existencia.
El archivo .lnk es el acceso directo que usarías para ejecutar la aplicación normalmente desde el Escritorio de Windows.
Por ejemplo:
Ahora tienes un acceso directo llamado MiERP en el escritorio
Mueve ese acceso directo a una carpeta del disco, por ejemplo d:\MisApps
Tendrás entonces un archivo d:\MisApps\MiERP.lnk
Copia a esta carpeta el ejecutable AutoIt compilado _lanzador_velneo.exe después de haber añadido la aplicación en la sección correspondiente:
Switch $CmdLine[1]
case "MiERP"
$cAccesoDirecto = "MiERP.lnk"
$cTitulo = "Mi Aplicación ERP"
case "0PS_APP_2"
.....
EndSwitch
El Título debe ser el mismo que has asignado al AUTOEXEC de la aplicación.
Crea un nuevo Acceso directo al lanzador de aplicaciones (Lanzador_MiERP) con el parámetro MiERP >>>> d:\MisApps\_lanzador_velneo.exe MiERP
Este nuevo Acceso directo Lanzador_MiERP es el que usará a partir de ahora el Usuario para prevenir ejecuciones simultáneas desde un mismo PC.
El lanzador _lanzador_velneo.exe buscará el Acceso directo MiERP.lnk en la misma carpeta y lo ejecutará en el caso de que la aplicación no esté ejecutándose.