Hola chavales, en el curro me he topado con un problema con unas viejas impresoras matriciales.
Resulta que el programa que envía los datos a imprimir, los manda "en crudo" ("raw" para los colegas).
Explico, nosotros tenemos un driver que suplanta una impresora Postscript y crea un PDF. Pues bien, la impresión "en crudo" lo que hace básicamente el saltarse el driver a la torera y enviar los datos directamente al puerto.
Para hacer las pruebas pertinentes, utilizamos un programita de Micro$oft:
https://support.microsoft.com/es-es/kb/138594?wa=wsignin1.0
Gracias a las pruebas con este programita detectamos que el driver no se ejecutaba, y que los datos iban del tirón al puerto en cuestión.
Así que ya sabéis que si una impresora matricial no funciona, quizá la culpa no sea del driver.
Salu2 a to2
lunes, 16 de marzo de 2015
jueves, 5 de marzo de 2015
Trabajo con impresoras desde la línea de comandos en Windows
Hola a todos, hoy se ma ha planteado la necesidad de ver cómo se puede cambiar el nombre de una impresora desde la línea de comandos de Windows.
Pues bien, resulta que Microsoft incorpora una serie de Scripts VBS para trabajar con las impresoras.
https://technet.microsoft.com/es-es/library/cc771846%28v=ws.10%29.aspx
Lo primero es localizar estos scripts en el ordenador. En el servidor donde estaba trabajando se encontraban en la ruta C:\Windows\System32\Printing_Admin_Scripts\es-ES\
A partir de ahí puedes utilizar estos scripts para hacer cosas como listar las impresoras del sistema:
cscript prnmngr.vbs -l
O cambiar el nombre de una impresora:
cscript prncnfg.vbs -x -p "Microsoft XPS Document Writer" -z XPS
Salu2 a to2
Pues bien, resulta que Microsoft incorpora una serie de Scripts VBS para trabajar con las impresoras.
https://technet.microsoft.com/es-es/library/cc771846%28v=ws.10%29.aspx
Lo primero es localizar estos scripts en el ordenador. En el servidor donde estaba trabajando se encontraban en la ruta C:\Windows\System32\Printing_Admin_Scripts\es-ES\
A partir de ahí puedes utilizar estos scripts para hacer cosas como listar las impresoras del sistema:
cscript prnmngr.vbs -l
O cambiar el nombre de una impresora:
cscript prncnfg.vbs -x -p "Microsoft XPS Document Writer" -z XPS
Salu2 a to2
domingo, 1 de marzo de 2015
Comparando antes y después con Windows
Hola a todos. En un servidor con Windows Server 2012 tenemos una aplicación que cuando un usuario con privilegios de administrador instalaba, dicha aplicación funcionaba correctamente.
Pero si se borraba el perfil local de la máquina (teniendo "roaming profiles" en el Active Directory), tras iniciar sesión en el servidor la aplicación ya no funcionaba.
Dicha aplicación se instala en el perfil del usuario, algo nada recomendable pero por lo que se ve los programadores de esta aplicación lo hicieron así. Así que cuando ese "perfil movil" se movía, había algo de la aplicación que no se estaba moviendo correctamente.
Después de muchos quebraderos de cabeza y muuuuuuuchas horas de trabajo, conseguimos averiguar qué era y solucionar el problema. Para ello usamos el software "Process Monitor".
https://technet.microsoft.com/es-es/sysinternals/bb896645.aspx
Partiendo de un perfil limpio, instalamos la aplicación y luego lanzamos el process monitor.
Aplicamos todos los filtros necesarios para excluir de la captura de eventos los procesos típicos del sistema (como el "task manager", o el "svchost"), y lanzamos la apliación que lógicamente funcionó correctamente. Luego guardamos la captura como CSV.
Tras esto, cerramos sesión, borramos el perfil local y a tras traerse el perfil móvil hicimos otra captura de eventos con el Process Monitor, pero esta vez sabíamos que la aplicación fallaría.
Una vez que teníamos 2 ficheros CSV (una con los eventos cuando la aplicación funciona y otra cuando no funciona). Los abrimos con Excel y quitamos las columnas de fecha y hora, y del ID de proceso. De esta forma los dos ficheros CSV son similares hasta el punto donde falla la aplicación.
Finalmente, comparando ambos ficheros CSV con Winmerge (que para algo son ficheros de texto), pudimos ver que nos faltaban algunas entradas del registro e incluso una librería DLL.
RESUMIENDO: Si queréis comparar un "antes" y un "después" del comportamiento de una aplicación, el "Process Monitor" es un buen aliado.
Salu2 a to2
Pero si se borraba el perfil local de la máquina (teniendo "roaming profiles" en el Active Directory), tras iniciar sesión en el servidor la aplicación ya no funcionaba.
Dicha aplicación se instala en el perfil del usuario, algo nada recomendable pero por lo que se ve los programadores de esta aplicación lo hicieron así. Así que cuando ese "perfil movil" se movía, había algo de la aplicación que no se estaba moviendo correctamente.
Después de muchos quebraderos de cabeza y muuuuuuuchas horas de trabajo, conseguimos averiguar qué era y solucionar el problema. Para ello usamos el software "Process Monitor".
https://technet.microsoft.com/es-es/sysinternals/bb896645.aspx
Partiendo de un perfil limpio, instalamos la aplicación y luego lanzamos el process monitor.
Aplicamos todos los filtros necesarios para excluir de la captura de eventos los procesos típicos del sistema (como el "task manager", o el "svchost"), y lanzamos la apliación que lógicamente funcionó correctamente. Luego guardamos la captura como CSV.
Tras esto, cerramos sesión, borramos el perfil local y a tras traerse el perfil móvil hicimos otra captura de eventos con el Process Monitor, pero esta vez sabíamos que la aplicación fallaría.
Una vez que teníamos 2 ficheros CSV (una con los eventos cuando la aplicación funciona y otra cuando no funciona). Los abrimos con Excel y quitamos las columnas de fecha y hora, y del ID de proceso. De esta forma los dos ficheros CSV son similares hasta el punto donde falla la aplicación.
Finalmente, comparando ambos ficheros CSV con Winmerge (que para algo son ficheros de texto), pudimos ver que nos faltaban algunas entradas del registro e incluso una librería DLL.
RESUMIENDO: Si queréis comparar un "antes" y un "después" del comportamiento de una aplicación, el "Process Monitor" es un buen aliado.
Salu2 a to2
martes, 17 de febrero de 2015
PnaclCoordinator: pexe load failed (pp_error=-2).
Hola a todos, hoy me he encontrado el siguiente error al intentar depurar el código PNaCL:
NaCl module load failed: PnaclCoordinator: pexe load failed (pp_error=-2).
Por lo visto, este código lo que indica es que no se ha podido descargar el PEXE. Así que le dí a F12, puse el navegador para ver los elementos que se descargan de la red, y vi que no tenía puesto el "*_unstripped.bc" en el servidor web.
Salu2 a to2
NaCl module load failed: PnaclCoordinator: pexe load failed (pp_error=-2).
Por lo visto, este código lo que indica es que no se ha podido descargar el PEXE. Así que le dí a F12, puse el navegador para ver los elementos que se descargan de la red, y vi que no tenía puesto el "*_unstripped.bc" en el servidor web.
Salu2 a to2
PNaCl ABI verification failed
Hola a todos, ayer estuve todo el día depurando en NaCL y cuando compilé la versión final con PNaCL me encontré el siguiente mensaje de error:
ERROR [NaCl module load failed: PnaclCoordinator: PNaCl Translator Error: PNaCl ABI verification failed]
Tras mucho investigar resulta que tenía definida la variable del entorno NACL_SDK_ROOT apuntando a "pepper_canary" mientras que estaba intentando compilar con "pepper_39".
Así que la causa del problema es que estaba mezclando código de dos NaCL SDK distintos.
Cambié la variable para que apuntara a "pepper_39", recompilé todo y ya funciona.
Salu2 a to2
miércoles, 28 de enero de 2015
Construyendo los naclports
Hola a todos, estoy estudiando el uso de PNaCL para crear un cliente nativo de Chrome para los Chrome books.
Esta es sólo una de las opciones a estudio para ver con cuál de las opciones tendremos en menor tiempo y con menor esfuerzo una versión del cliente de nuestro software para Chromium.
Como parte de las dependencias de nuestro software está OpenSSL, así que viendo por la web encontré que lo mejor es tirar de los "naclports".
Para construir los "naclports" necesitarás:
Esta es sólo una de las opciones a estudio para ver con cuál de las opciones tendremos en menor tiempo y con menor esfuerzo una versión del cliente de nuestro software para Chromium.
Como parte de las dependencias de nuestro software está OpenSSL, así que viendo por la web encontré que lo mejor es tirar de los "naclports".
Para construir los "naclports" necesitarás:
- Ubuntu 14 de 64 bits (no uses Debian porque encontrarás problemas con las versiones)
- Descargar el "nacl_sdk" (debes descargar "pepper_canary")
- Descargar los "naclports".
Como hay partes del "nacl_sdk" compilado para amd64 y partes compiladas para i386, necesitas la versión de 64 bits y obtener las librerías de 32 bits y las herramientas necesarias para la compilación mediante:
sudo apt-get install git curl lib32stdc++6 g++ lib32z1 lib32ncurses5 lib32bz2-1.0
Una vez hecho esto descaga el "nacl_sdk" y los "naclports" siguiendo los pasos indicados en:
Cuando ya has obtenido todo el software podrás construir la librería "openssl" mediante:
cd naclports/src
export NACL_SDK_ROOT=/home/usuario/chrome/nacl_sdk/pepper_canary
export BUILDBOT_BUILDERNAME=true
NACL_ARCH=pnacl TOOLCHAIN=pnacl make openssl
Si todo va bien deberá construirse la librería sin dar ningún error.
Un saludo
jueves, 18 de diciembre de 2014
Sockets no bloqueantes en Python
Hola a todos. El uso de sockets es sin duda uno de los recursos más utilizados que hay, y también uno de los peor utilizados.
Los sockets pueden configurarse como bloqueantes (por defecto) o hacerlos no bloqueantes mediante "fcntl" con el "flag" O_NONBLOCK. Y la diferencia es brutal.
Un socket bloqueante detendrá la ejecución del programa cuando se haga una llamada a "recv" y no haya datos para recibir. Y cuando se reciban los datos la ejecución continuará.
Mientras que un socket bloqueante, al hacer "recv" si hay datos se obtienen y si no los hay se devuelve una excepción con un valor "errno" de 11 (EAGAIN), que nos indicará básicamente un "prueba otra vez".
Pues bien, en un programa con sockets supuestamente bloqueantes vi que se comportaban como no bloqueantes sin razón aparente y he tardado 3 días en encontrar la solución.
El problema era debido al "timeout" por defecto. Me explico. En Python el "timeout" por defecto para los sockets está establecido a "None". Esto significa que si se intenta establecer una conexión con un host remoto y la conexión no se establece vaya usted a saber por qué, el programa se queda esperando indefinidamente ya que no hay un timeout.
Así, que en su día hice el cambio de establecer un "timeout" por defecto de 30 segundos. Y un tiempo después (hace 3 días), se detectó un problema derivado de esta decisión.
Y es que al establecer el timeout los sockets se vuelven no bloqueantes. Pero es más, muchos ni siquiera esperan esos 30 segundos.
¿Que cómo es esto posible? Porque no todos los sockets son del mismo tipo ni se usan para lo mismo.
Los sockets que establecen una conexión con un host remoto sí funcionan correctamente (con su timeout de 30 segundos), pero los sockets que se utilizan para la comunicación entre procesos con la librería "multiprocessing", estos funcionan como sockets no bloqueantes y no respetan el timeout de 30 segundos.
Así que la comunicación entre procesos "con multiprocessing.Pipe", y "multiprocessing.Listener" (usado dentro "multriprocessing,reduce_handle"), sencillamente no funcionaba.
Con lo que el resultado es que he tenido que quitar el timeout por defecto de 30 segundos, dejarlo como "None", y poner el timeout de 30 segundos sólo a aquellos sockets que me interesaban.
RESUMIENDO: No se puede establecer un timeout por defecto si usas comunicación entre procesos con la librería "multiprocesing"
Salu2 a to2
Los sockets pueden configurarse como bloqueantes (por defecto) o hacerlos no bloqueantes mediante "fcntl" con el "flag" O_NONBLOCK. Y la diferencia es brutal.
Un socket bloqueante detendrá la ejecución del programa cuando se haga una llamada a "recv" y no haya datos para recibir. Y cuando se reciban los datos la ejecución continuará.
Mientras que un socket bloqueante, al hacer "recv" si hay datos se obtienen y si no los hay se devuelve una excepción con un valor "errno" de 11 (EAGAIN), que nos indicará básicamente un "prueba otra vez".
Pues bien, en un programa con sockets supuestamente bloqueantes vi que se comportaban como no bloqueantes sin razón aparente y he tardado 3 días en encontrar la solución.
El problema era debido al "timeout" por defecto. Me explico. En Python el "timeout" por defecto para los sockets está establecido a "None". Esto significa que si se intenta establecer una conexión con un host remoto y la conexión no se establece vaya usted a saber por qué, el programa se queda esperando indefinidamente ya que no hay un timeout.
Así, que en su día hice el cambio de establecer un "timeout" por defecto de 30 segundos. Y un tiempo después (hace 3 días), se detectó un problema derivado de esta decisión.
Y es que al establecer el timeout los sockets se vuelven no bloqueantes. Pero es más, muchos ni siquiera esperan esos 30 segundos.
¿Que cómo es esto posible? Porque no todos los sockets son del mismo tipo ni se usan para lo mismo.
Los sockets que establecen una conexión con un host remoto sí funcionan correctamente (con su timeout de 30 segundos), pero los sockets que se utilizan para la comunicación entre procesos con la librería "multiprocessing", estos funcionan como sockets no bloqueantes y no respetan el timeout de 30 segundos.
Así que la comunicación entre procesos "con multiprocessing.Pipe", y "multiprocessing.Listener" (usado dentro "multriprocessing,reduce_handle"), sencillamente no funcionaba.
Con lo que el resultado es que he tenido que quitar el timeout por defecto de 30 segundos, dejarlo como "None", y poner el timeout de 30 segundos sólo a aquellos sockets que me interesaban.
RESUMIENDO: No se puede establecer un timeout por defecto si usas comunicación entre procesos con la librería "multiprocesing"
Salu2 a to2
Suscribirse a:
Entradas (Atom)