Ejecutar proceso en Mono/C# sobre ubuntu

Iniciado por unjust63, 10 Febrero 2010, 19:54 PM

0 Miembros y 1 Visitante están viendo este tema.

unjust63

Hola.

Realizo lo siguiente en mono:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "gnome-sudoku"
p.Start();
p.WaitForInputIdle();

y posteriormente y a continuación en el código, realizo lo siguiente:

Process sk = new Process();
sk.StartInfo.FileName = "xsendkeys";
sk.StartInfo.Arguments = 95; //corresponde a la tecla F11
sk.Start();


Lo que quiero hacer, es mandar la tecla F11 a la ventana activa, y
funciona, sólo que la tecla se manda sin parar. Quiero decir que es como
si dejara la tecla F11 pulsada sobre la ventana de gnome-sudoku, por lo
que la ventana no para de bailar. Lo he probado también con xdotool y
sucede igual. System.Windows.Forms.SendKeys.Send no funciona, al parecer
, sobre ventanas gtk.

Si lo hago directamente sobre una ventana de shell, funciona bien. Es
como si el process.start() no terminara de funcionar bien, y yo no
supiera hacerlo como se debe.

Alguna idea? Gracias por adelantado.

Juan Carlos F.

Keyen Night

Usa SendMessage con las intrucciones WM_CHAR, WM_KEYDOWN y WM_KEYUP.
Es la forma más sencilla de enviar teclas a aplicaciones externas sin que se pierdan hacia otro lado simplemente enviarlas al handle...
Aquí te pongo un ejemplo de un void llamado SendKey
Código (c#) [Seleccionar]

   public const int WM_CHAR = 0x102;
   public const int WM_KEYDOWN = 0x100;
   public const int WM_KEYUP = 0x101;

public static void SendKey(IntPtr mHandle, int key)
{
   SendMessage(mHandle, WM_KEYDOWN, key, 0);
   SendMessage(mHandle, WM_CHAR, key, 0);
   SendMessage(mHandle, WM_KEYUP, key, 0);
   Thread.Sleep(0x19);
}


Lo use y lo sigo usando es my efectivo :P
La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...

Foxy Rider

#2
@Keyen : Lamento pincharte el globo, pero dijo mono/ubuntu, que ... ah si, es LINUX | me gustaría que te tomes la molestia de leer un poquito más el thread antes de postear  (perdón si soné agresivo, pero la gente que postea sin leer me saca de quicio ... gracias !)

@unjust63 : Hola ! justo vi tu mail en la lista de correo de mono ....
te comento, si el xsendkeys es este que creo : http://people.csail.mit.edu/adonovan/hacks/xsendkey.html (el code es correcto, ya que hace el release y tiene el count en 1 como default)

entonces no debería haber problemas con esto (no lo probé con gnome-sudoku, ya que trato de mantener mi sistema limpio de las librerías GTK, pero sí con otras apps.) :

Código (csharp) [Seleccionar]

using System;
using System.Diagnostics;

namespace KeySend
{
 class keyDemo
 {
   public static void Main()
   {

     // aca te toca iniciar el proceso que quieras para obtener foco
     // o indicar el ID de la ventana como parametro a xsendkeys
     // (lo mas apropiado seria esto, sin duda)

     Process mProcess = new Process();
     mProcess.StartInfo.FileName = "./xsendkeys";
     mProcess.StartInfo.Arguments = "F11";
     mProcess.Start();
   }
 }

}



todo va de 10, ¿no veo el problema ?  :-\

Saludos ~

unjust63

Buenas Vertex.Symphony.

Gracias por la respuesta. El caso es que sobre la consola va perfecto, pero si la ventana activa es otra que no sea la consola (di gnome-sudoku, di cualquier otra que admita el f11) la pulsación de tecla se mantiene. Es algo muy raro... no lo consigo hacer funcionar.

Te agradecería que intentaras realizarlo sobre cualquier otra ventana activa y me dijeras que sucede. En mi caso, el xsendkeys sobre cualquier otra ventana que no sea la consola no funciona, y el xsendkeycode funciona, pero mal.

Gracias por las molestias.
Juan Carlos.

elmaro

Buenas.
Y si pruebas finalizando el proceso?

Código (csharp) [Seleccionar]
mProcess.Kill();

unjust63

Hola.

Ya lo probé. Si hago un Kill justo despues del Start, no funciona, ya que no da tiempo a ejecutarse el proceso, y si lo hago esperando unos segundos, o despues del waitforinputidle, hace lo mismo que sin el kill. El caso es que el proceso ha terminado de ejecutarse, ya no está en la lista de procesos de ps -e, pero la pulsación de la tecla, se repite sin parar. Es como dejar la tecla pulsada.

elmaro

Cita de: unjust63 en 11 Febrero 2010, 19:37 PM
Hola.

Ya lo probé. Si hago un Kill justo despues del Start, no funciona, ya que no da tiempo a ejecutarse el proceso, y si lo hago esperando unos segundos, o despues del waitforinputidle, hace lo mismo que sin el kill. El caso es que el proceso ha terminado de ejecutarse, ya no está en la lista de procesos de ps -e, pero la pulsación de la tecla, se repite sin parar. Es como dejar la tecla pulsada.

Entonces supongo que ya probaste antes del Start

Código (csharp) [Seleccionar]
mProcess.WaitForExit();

De todas formas, si la tecla queda pulsada no hay una forma de "despulsarla" usando algo similar al SendMessage?. Nunca llegue a programar en Ubuntu lamentablemente

Saludos

Foxy Rider

#7
Es por eso que dije que el código del xsendkeys es correcto, si vamos a este pasaje del código (donde se envía la tecla y después el release) :

Código (cpp) [Seleccionar]
SendEvent(&event);

event.type = KeyRelease;
SendEvent(&event);


Acá lo probé de esta forma :

Código (csharp) [Seleccionar]

using System;
using System.Diagnostics;
using System.Threading;

namespace KeySend
{
 class keyDemo
 {
   public static void Main()
   {
     Process mApp = new Process();
     mApp.StartInfo.FileName = "google-chrome";
     mApp.Start();

     Thread.Sleep(5000);

     Process mProcess = new Process();
     mProcess.StartInfo.FileName = "./xsendkeys";
     mProcess.StartInfo.Arguments = "F11";
     mProcess.Start();
   }
 }

}


y me fue de 10, me puso el chrome en pantalla completa ...
fijate si el code del xsendkeys es el mismo que el mío y probalo, ya que en ese sitio leí que tenía un parche....

si no tuviste éxito,me instalo el gnome-sudoku en una máquina virtual, veo cual es el problema y te modifico el xsendkeys para que cumpla su función  ...

Saludos ~

unjust63

Buenas Vertex.Symphony .

Pues voy a bajarme ese código, lo compilo y te digo. Aunque me bajé también la aplicacion xdotool que hace lo mismo (y más cosas) y también funciona mal.

Te digo algo en probarlo todo. Gracias por las molestias.