2017-09-17 2 views
-1

J'ai une situation intéressante. J'essaie d'exécuter un programme à partir de la ligne de commande et je ne peux pas rediriger par programmation son entrée pour une raison quelconque. L'exécutable que je cours est appelé. Spideroakone.exe. Cet exécutable demande un mot de passe. Quand je tape le mot de passe disons que le mot de passe est "asd" je peux réellement voir ce que je tape en texte clair. Je reçois un message d'erreur:C# application de console d'entrée de redirection ne fonctionne pas

'asd' is not recognized as an internal or external command ... 

Si je lance le fichier exécutable comme ça:

cmd /c Spideroakone.exe 

puis de nouveau je vois la même on me demande un mot de passe. Ensuite, je tape asd. Mais je ne peux pas voir ce que je tape et le mot de passe fonctionne et il n'y a pas d'erreur.

Maintenant, ce que je veux faire est d'écrire une application qui va exécuter Spideroak.exe et passer le mot de passe sur l'entrée standard. Cependant, en raison du comportement étrange de Spideroak, je ne peux pas passer d'entrée standard et je ne peux pas lire la sortie standard. Lorsque vous essayez de faire cela, mon application bloque sur la commande writeline. Je m'attendais à voir le mot "Password:" dans la stdout. J'ai essayé quelques exemples asynchrones et multithread mais pas de cela fonctionne. Le tampon de sortie standard est toujours vide. Je me demande quel est ce texte que je vois "Mot de passe:" s'il n'est pas écrit dans la stdout où il est écrit?

c'est le code que j'utilise. Quels blocs sur la ligne ReadToEnd(). Ce code exact fonctionne très bien avec une application de la console que je fait si cela me fait penser l'exécutable que je suis en train d'exécuter est écrit d'une manière bizarre, mais dans une fenêtre de ligne de commande, il fonctionne très bien:

Process myProcess = new Process(); 

myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe"; 
myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless"; 
myProcess.StartInfo.UseShellExecute = false; 
myProcess.StartInfo.RedirectStandardOutput = true; 
myProcess.StartInfo.RedirectStandardInput = true; 

myProcess.Start(); 

string s = myProcess.StandardOutput.ReadToEnd(); 
myProcess.WaitForExit(); 

C'est la capture d'écran de la fenêtre de débogage exacte et les blocs ligne iT sur:

Voici ce que je vois dans la fenêtre de ligne de commande:

+0

S'il vous plaît modifier votre question et ajouter du code pour fournir [mcve] (https://stackoverflow.com/help/mcve) –

+0

Est-ce que quelqu'un sait aussi comment rediriger la sortie du cmd actuellement ouvert dans un fichier . Je veux dire quand je tape asdf sur l'invite de commande, je vais voir un message '... n'est pas reconnu comme une commande interne ou externe ...' Je veux voir ce message dans un fichier. Comment fait-on cela? cela pourrait être lié à mon problème. –

+0

Non ce n'est pas ça. En effet, la sortie d'erreur est différente de la sortie standard. –

Répondre

0

Eh bien personne n'a répondu et en attendant j'ai trouvé la réponse. Je n'ai pas trouvé la raison exacte pour laquelle stdout et stdin ne fonctionnent pas mais j'ai lu un article que quelqu'un d'autre se plaignait que les anciens programmes écrits en C en utilisant getch() se comportent de cette façon. Je voulais le faire d'une manière plus jolie mais c'est ce que j'ai trouvé. Envoi basique de touches à la fenêtre de la console. Je n'étais pas sûr si cela fonctionnerait parce que je commence le processus dans le planificateur de tâches et il n'y a aucune fenêtre visuelle créée mais cela fonctionne bien.

Je commence le processus dans un thread séparé:

new Thread(() => 
     { 
     Process myProcess = new Process(); 

     myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe"; 
     myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless"; 
     myProcess.StartInfo.UseShellExecute = false; 
     myProcess.Start(); 

     myProcess.WaitForExit(); 
     }).Start(); 

J'énumèrent toutes les fenêtres:

EnumWindows(EnumTheWindows, IntPtr.Zero); 

Je cherche la fenêtre de mon processus et envoie les coups clés souhaités à ce . Le sommeil entre les deux est nécessaire sans qu'il ne fonctionne pas. Le mot de passe d'exemple que je vous envoie est « asd »

private static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam) 
    { 
     uint pidCurWindow; 
     uint CurWindowThreadId = GetWindowThreadProcessId(hWnd, out pidCurWindow); 
     int CurrentPID = System.Diagnostics.Process.GetCurrentProcess().Id; 

     if (pidCurWindow == CurrentPID) 
     { 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('a'), 0); 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('s'), 0); 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('d'), 0); 
      Thread.Sleep(50); 
      PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1); 
      Thread.Sleep(50); 
     } 
     return true; 
    } 

J'espère que cela aidera quelqu'un à gagner du temps.