Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Proyecto SIF/Veri*Factu/Ley Antifraude > General/Noticias
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-12-2024
razorxxx razorxxx is offline
Miembro
 
Registrado: jul 2015
Posts: 108
Poder: 10
razorxxx Va por buen camino
Ver si proceso en ejecución en máquina remota

Buenas a todos!

En mi empresa tenemos múltiples sistemas de facturación ya que programamos a medida para nuestros clientes. Es por ello que la adaptación a Veri*Factu la haremos haciendo uso de un subprograma que mostrará el registro de facturación asociado a una factura, gestionará los envíos y respuestas, las firmas, los registros de eventos, etc.

Como la mayoría de nuestras instalaciones son de tipo cliente-servidor, el subprograma en cuestión se ejecutará en el servidor y estará siempre disponible, y se mantendrá a la escucha para enviar los registros cada 60 segundos.

Lo que pasa es que este subprograma, por razones diversas, podría ocurrir que de repente se cuelgue y deje de estar disponible para el envío de las facturas. Por tanto, cada uno de nuestros SIF debería detectar antes o después de generar el registro de una factura si dicho subprograma está en ejecución en la máquina remota para, en caso contrario, ejecutarlo o que nos avise por mail de que no está ejecutándose, pues de lo contrario no se podrían remitir los registros de facturación a la AEAT.

¿Alguno de ustedes sabe cómo puede consultarse desde un equipo si en otro equipo de la red existe un proceso en ejecución? Tras algunas consultas a Google y otras a Copilot, he estado probando la api de WMI pero hasta ahora no consigo que funcione. Mi código es el siguiente:

Código:
var
   SWbemLocator: OLEVariant;
   SWbemServices: OLEVariant;
   SWbemObjectSet: OLEVariant;
   SWbemObject: OLEVariant;
   Enum: IEnumVariant;
   Value: Cardinal;
begin
     Result := False;
     SWERROR := 0;
     try
        CoInitialize(nil);
             try
                SWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
                If CBCredenciales.Checked Then  // Si la máquina remota tiene autenticación
                    SWbemServices := SWbemLocator.ConnectServer(RemoteMachine, 'root\CIMV2', Usuario.Text, Password.Text)
                Else
                    SWbemServices := SWbemLocator.ConnectServer(RemoteMachine, 'root\CIMV2', '', '');
                SWbemObjectSet := SWbemServices.ExecQuery(Format('SELECT * FROM Win32_Process WHERE Name = "%s"', [ProcessName]));
                Enum := IUnknown(SWbemObjectSet._NewEnum) as IEnumVariant;
                while Enum.Next(1, SWbemObject, Value) = S_OK do
                begin
                     Result := True;
                     SWbemObject := Unassigned;
                end;
             finally
                    CoUninitialize;
             end;
     except
           on E: EOleException do
           begin
                SWERROR := 1;
                Memo1.Lines.Add(Format('Error %d : ($%x) Mensaje : %s', [E.ErrorCode, E.ErrorCode, E.Message]));
           end;
           on E: Exception do
           begin
                SWERROR := 1;
                Memo1.Lines.Add('Error ' + E.Classname + ': ' + E.Message);
           end;
     end;
end;
Casi seguro está relacionado con temas de firewall y puertos en la máquina remota, porque si activo o desactivo el Firewall recibo errores diferentes.
Responder Con Cita
  #2  
Antiguo 09-12-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 1.768
Poder: 5
ermendalenda Va por buen camino
Cita:
Empezado por razorxxx Ver Mensaje
Buenas a todos!

En mi empresa tenemos múltiples sistemas de facturación ya que programamos a medida para nuestros clientes. Es por ello que la adaptación a Veri*Factu la haremos haciendo uso de un subprograma que mostrará el registro de facturación asociado a una factura, gestionará los envíos y respuestas, las firmas, los registros de eventos, etc.

Como la mayoría de nuestras instalaciones son de tipo cliente-servidor, el subprograma en cuestión se ejecutará en el servidor y estará siempre disponible, y se mantendrá a la escucha para enviar los registros cada 60 segundos.

Lo que pasa es que este subprograma, por razones diversas, podría ocurrir que de repente se cuelgue y deje de estar disponible para el envío de las facturas. Por tanto, cada uno de nuestros SIF debería detectar antes o después de generar el registro de una factura si dicho subprograma está en ejecución en la máquina remota para, en caso contrario, ejecutarlo o que nos avise por mail de que no está ejecutándose, pues de lo contrario no se podrían remitir los registros de facturación a la AEAT.

¿Alguno de ustedes sabe cómo puede consultarse desde un equipo si en otro equipo de la red existe un proceso en ejecución? Tras algunas consultas a Google y otras a Copilot, he estado probando la api de WMI pero hasta ahora no consigo que funcione. Mi código es el siguiente:

Código:
var
   SWbemLocator: OLEVariant;
   SWbemServices: OLEVariant;
   SWbemObjectSet: OLEVariant;
   SWbemObject: OLEVariant;
   Enum: IEnumVariant;
   Value: Cardinal;
begin
     Result := False;
     SWERROR := 0;
     try
        CoInitialize(nil);
             try
                SWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
                If CBCredenciales.Checked Then  // Si la máquina remota tiene autenticación
                    SWbemServices := SWbemLocator.ConnectServer(RemoteMachine, 'root\CIMV2', Usuario.Text, Password.Text)
                Else
                    SWbemServices := SWbemLocator.ConnectServer(RemoteMachine, 'root\CIMV2', '', '');
                SWbemObjectSet := SWbemServices.ExecQuery(Format('SELECT * FROM Win32_Process WHERE Name = "%s"', [ProcessName]));
                Enum := IUnknown(SWbemObjectSet._NewEnum) as IEnumVariant;
                while Enum.Next(1, SWbemObject, Value) = S_OK do
                begin
                     Result := True;
                     SWbemObject := Unassigned;
                end;
             finally
                    CoUninitialize;
             end;
     except
           on E: EOleException do
           begin
                SWERROR := 1;
                Memo1.Lines.Add(Format('Error %d : ($%x) Mensaje : %s', [E.ErrorCode, E.ErrorCode, E.Message]));
           end;
           on E: Exception do
           begin
                SWERROR := 1;
                Memo1.Lines.Add('Error ' + E.Classname + ': ' + E.Message);
           end;
     end;
end;
Casi seguro está relacionado con temas de firewall y puertos en la máquina remota, porque si activo o desactivo el Firewall recibo errores diferentes.
Puedes crear un archivo bloqueado(locked mode) y lo dejas abierto en el programa del srvidor, cuando esté cerrado dicho programa, el archivo se desbloqueará y los programas de cliente que intenten escribir algo en ese archivo y si deja (no devolviendo error de bloqueo) es que está cerrado.

Última edición por ermendalenda fecha: 09-12-2024 a las 12:25:45.
Responder Con Cita
  #3  
Antiguo 09-12-2024
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.874
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por razorxxx Ver Mensaje
Lo que pasa es que este subprograma, por razones diversas, podría ocurrir que de repente se cuelgue y deje de estar disponible para el envío de las facturas. Por tanto, cada uno de nuestros SIF debería detectar antes o después de generar el registro de una factura si dicho subprograma está en ejecución en la máquina remota para, en caso contrario, ejecutarlo o que nos avise por mail de que no está ejecutándose, pues de lo contrario no se podrían remitir los registros de facturación a la AEAT.
¿Porqué no usáis un servicio?
Yo creo que sería lo adecuado para este escenario.
Para consultar si un servicio está en marcha, se podría utilizar WMI.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 11-12-2024
nincillo nincillo is offline
Miembro
 
Registrado: may 2017
Posts: 178
Poder: 8
nincillo Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
¿Porqué no usáis un servicio?
Yo creo que sería lo adecuado para este escenario.
Para consultar si un servicio está en marcha, se podría utilizar WMI.
Yo había pensado en abrir un puerto y por sockets hacer llamadas cada vez que se genera una factura para que el programa "externo" proceda al envío y sino hay respuesta a la petición avisar del problema.

Pero si ese programa remoto fuera ejecutado como un servicio, creo que mucho mejor.

¿Podrías orientarnos un poco el como hacer un programa que funcione como un servicio?
Responder Con Cita
  #5  
Antiguo 11-12-2024
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.874
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por nincillo Ver Mensaje
Yo había pensado en abrir un puerto y por sockets hacer llamadas cada vez que se genera una factura para que el programa "externo" proceda al envío y sino hay respuesta a la petición avisar del problema.

Si es posible, lo más sencillo (creo yo) es que tantos los programas cliente (ERP) como el servicio (o la app. que habías pensado) estén conectados a la Base de Datos.
Los ERP van colocando ficheros en la cola (es una o varias tablas dependiendo del diseño) y el servicio los va procesando y en la misma Base de Datos va generando las respuestas.
La lógica de envío sólo está en el servicio.



Cita:
Empezado por nincillo Ver Mensaje
¿Podrías orientarnos un poco el como hacer un programa que funcione como un servicio?

Nosotros diseñamos el servicio en 2 piezas (EXE + DLL). En realidad para facilitar debug y pruebas, se diseña un servicio y una aplicación.
Para no "repetir" código, toda la lógica se encuentra en la DLL y esa DLL se llama desde una APP y desde un SERVICIO.
Como he dicho la APP y el SERVICIO sólo tienen una llamada al método de "procesar" de la DLL (que tiene toda la lógica).


¿Porqué se hace esto? Porque los servicios no pueden tener parte visual y los LOGs para debug se envían al registro de eventos de Windows, en el caso de la APP sí puede tener parte visual y los LOGs para debug se envían a un fichero. Para todo el proceso de desarrollo se usa la APP+DLL y para el cliente final SERVICIO+DLL.



Si buscas por los foros encontrarás muchos hilos al respecto y posiblemente en el FTP encontrarás algún ejemplo:
https://www.clubdelphi.com/foros/showthread.php?t=89341
https://www.clubdelphi.com/foros/showthread.php?t=48843
https://www.clubdelphi.com/foros/showthread.php?t=12776
https://www.clubdelphi.com/foros/showthread.php?t=20913
https://www.intitec.com/varios/delph...io_windows.pdf
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #6  
Antiguo 11-12-2024
RUBEN_SP RUBEN_SP is offline
Miembro
 
Registrado: mar 2008
Posts: 24
Poder: 0
RUBEN_SP Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
Si es posible, lo más sencillo (creo yo) es que tantos los programas cliente (ERP) como el servicio (o la app. que habías pensado) estén conectados a la Base de Datos.
Los ERP van colocando ficheros en la cola (es una o varias tablas dependiendo del diseño) y el servicio los va procesando y en la misma Base de Datos va generando las respuestas.
La lógica de envío sólo está en el servicio.
Y que paso si en el mismo servidor hay varias instancias de la Base de Datos porque hay varias instalaciones ¿Cómo sabe el servicio a cual tiene que atender?
Responder Con Cita
  #7  
Antiguo 11-12-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 1.768
Poder: 5
ermendalenda Va por buen camino
Cita:
Empezado por RUBEN_SP Ver Mensaje
Y que paso si en el mismo servidor hay varias instancias de la Base de Datos porque hay varias instalaciones ¿Cómo sabe el servicio a cual tiene que atender?
Lo más rápido es un registro de índice único autonumerico y controlar poner en bucle los reintentos por si coinciden 2 escrituras. Cuando te deje escribir obtienes el número que será único.
Los servicios se atienden a quien los pide, no se entremezclan y además puedes mandarles parámetros para identificar desde donde lo envías para que se registre.

Última edición por ermendalenda fecha: 11-12-2024 a las 21:33:24.
Responder Con Cita
  #8  
Antiguo 12-12-2024
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.874
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por RUBEN_SP Ver Mensaje
Y que paso si en el mismo servidor hay varias instancias de la Base de Datos porque hay varias instalaciones ¿Cómo sabe el servicio a cual tiene que atender?

Es cuestión de buscar soluciones a los problemas.
En nuestro caso hay un único Servidor de Base de Datos, pero puede haber varias Bases de Datos dentro de ese servidor.
Cada base de datos es una empresa/obligado diferente (no se si es también tu caso); El servicio hace y una rueda y se va conectando a las diferentes Bases de Datos para enviar los datos de esa empresa. Una vez acabado se apunta en tiempo de espera (o el tiempo hasta el siguiente envío) para esa empresa.

Es decir, en nuestro caso, un único servicio se encarga de todos los envíos de las diferentes empresas/obligados tributarios. Por ahora en el Thread principal, porque no contemplamos que la "rueda de envío" pueda tardar más de 60 sg. Actualmente se hace muy rápido. Si en su día esa "rueda de envíos" empezara a tardar mucho, nos planteamos crear Threads (ya lo tenemos pensado).
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #9  
Antiguo Hace 3 Semanas
ISCOPYME ISCOPYME is offline
Miembro
 
Registrado: jun 2004
Posts: 18
Poder: 0
ISCOPYME Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
Si es posible, lo más sencillo (creo yo) es que tantos los programas cliente (ERP) como el servicio (o la app. que habías pensado) estén conectados a la Base de Datos.
Los ERP van colocando ficheros en la cola (es una o varias tablas dependiendo del diseño) y el servicio los va procesando y en la misma Base de Datos va generando las respuestas.
La lógica de envío sólo está en el servicio.


Nosotros diseñamos el servicio en 2 piezas (EXE + DLL). En realidad para facilitar debug y pruebas, se diseña un servicio y una aplicación.
Para no "repetir" código, toda la lógica se encuentra en la DLL y esa DLL se llama desde una APP y desde un SERVICIO.
Como he dicho la APP y el SERVICIO sólo tienen una llamada al método de "procesar" de la DLL (que tiene toda la lógica).


¿Porqué se hace esto? Porque los servicios no pueden tener parte visual y los LOGs para debug se envían al registro de eventos de Windows, en el caso de la APP sí puede tener parte visual y los LOGs para debug se envían a un fichero. Para todo el proceso de desarrollo se usa la APP+DLL y para el cliente final SERVICIO+DLL.


Buenos días. A ver si alguien me puede dar alguna pista sobre el error que estoy teniendo. Yo hasta ahora tenía una dll que se encargaba de todo, el envío a la aeat, la respuesta, etc.... funcionando correctamente. Cuando he decidido crear un servicio que aproveche esta dll, mi sorpresa ha sido que no funciona correctamente, me da el siguiente error "Received content of invalid Content-Type setting: text/html - SOAP expects "text/xml".

¿ Alguien sabe algo de este error o me puede decir si se puede depurar un servicio en funcionamiento, para ver qué está pasando. ?

Muchas gracias.
Responder Con Cita
  #10  
Antiguo Hace 3 Semanas
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.874
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
¿Estás llamado a la URL correcta?
Deberás añadir log, para ver más o menos dónde está fallando.
CXreo que suele ser lo habitual, cuando el componente de envío no recibe una respuesta correcta al realizar la llamada, por ejemplo cuando la URL es incorrecta, pero sin saber algo más concreto es difícil.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #11  
Antiguo Hace 2 Semanas
aleixep aleixep is offline
Registrado
 
Registrado: ene 2025
Posts: 3
Poder: 0
aleixep Va por buen camino
Cita:
Empezado por ISCOPYME Ver Mensaje
Buenos días. A ver si alguien me puede dar alguna pista sobre el error que estoy teniendo. Yo hasta ahora tenía una dll que se encargaba de todo, el envío a la aeat, la respuesta, etc.... funcionando correctamente. Cuando he decidido crear un servicio que aproveche esta dll, mi sorpresa ha sido que no funciona correctamente, me da el siguiente error "Received content of invalid Content-Type setting: text/html - SOAP expects "text/xml".

¿ Alguien sabe algo de este error o me puede decir si se puede depurar un servicio en funcionamiento, para ver qué está pasando. ?

Muchas gracias.
Primero que nada, ¡hola a todos! Este es mi primer mensaje al foro, así que espero hacerlo bien.

En nuestro caso, ISCOPYME, nos salía ese error cuando no se enviaba correctamente el certificado electrónico. Si abres el navegador web, pegas esa URL y no seleccionas el certificado, la AEAT devuelve un HTML indicando el error 403. En nuestro caso, si el Delphi no encontraba el certificado, cuando hacía la petición al WebService sin él, también devolvía un HTML. ¡Espero que te sirva!

Última edición por aleixep fecha: Hace 2 Semanas a las 08:31:32. Razón: Añadí un emoticono pero no se veía
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Capturar id de maquina remota mediaplanet API de Windows 3 18-05-2010 10:46:09
Instalar un proceso de forma remota fide_32 API de Windows 1 26-09-2008 10:08:42
Ejecutar programa desde una maquina remota rjsitruiz Varios 0 12-01-2005 16:55:19
abrir un documento en una maquina remota CarlosHernandez API de Windows 2 10-03-2004 21:47:14
Nuevo Contacto en máquina remota Igna Servers 1 21-01-2004 18:47:24


La franja horaria es GMT +2. Ahora son las 07:05:08.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi