En Direct de la sortie du Processus
J'ai un problème dans mon projet. Je voudrais lancer un processus, 7z.exe (version console).
J'ai essayé trois choses différentes:
- Processus.StandardOutput.ReadToEnd();
- OutputDataReceived & BeginOutputReadLine
- StreamWriter
Rien ne fonctionne. Il est toujours "attendre" la fin du processus pour montrer ce que je veux.
Je n'ai pas de code pour mettre, simplement si vous voulez mon code avec l'une des choses énumérées upthere. Merci.
Edit:
Mon code:
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
this.sr = process.StandardOutput;
while (!sr.EndOfStream)
{
String s = sr.ReadLine();
if (s != "")
{
System.Console.WriteLine(DateTime.Now + " - " + s);
}
}
Ou
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler(recieve);
process.StartInfo.CreateNoWindow = true;
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
public void recieve(object e, DataReceivedEventArgs outLine)
{
System.Console.WriteLine(DateTime.Now + " - " + outLine.Data);
}
Ou
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
string output = p.StandardOutput.ReadToEnd();
process.WaitForExit();
Où "processus" est mon pré-Processus
Ok, je sais pas pourquoi ça ne fonctionne pas correctement: 7z.exe est le bug: il affiche un pourcentage de chargement de la console, et il envoie des informations uniquement lorsque le fichier en cours est terminé. Dans l'extraction, par exemple, il fonctionne très bien :). Je vais chercher un autre moyen d'utiliser 7z fonctions sans 7z.exe (peut-être avec 7za.exe ou avec une DLL). Merci à tous.
Pour répondre à la question, OuputDataRecieved événement fonctionne très bien !
- une raison quelconque vous n'utilisez pas le DLL/SDK downloadabe de 7zip qui permet un contrôle beaucoup plus grand que n'importe quelle console basée sur la technique ?
- Elle permettrait de voir le code que vous avez essayé avec un Processus où, par exemple, vous créez le Processus de
- Parce que 7z.exe couvre toutes les fonctions que je voulais.
- Jusqu' ? J'ai vraiment besoin d'aide. Je vais trie avec cmd. Je pense que le problème vient de la 7z.exe.
Vous devez vous connecter pour publier un commentaire.
Prendre un coup d'oeil à cette page, il recherche c'est la solution pour vous: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline.aspx et http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx
[Modifier]
C'est un exemple de travail:
Btw, ls -R C:\ répertorie tous les fichiers à la racine de C: de manière récursive. Il y a beaucoup de fichiers, et je suis sûr que ce n'est pas le cas lorsque les premiers résultats apparaissent à l'écran.
Il y a une possibilité 7zip contient la sortie avant de le montrer. Je ne suis pas sûr de ce que params vous donner à ce processus.
p.BeginErrorReadLine();
est nécessaire d'autre gestionnaire d'erreur n'est pas appeléeAfin de gérer correctement la sortie et/ou d'erreur de redirection, vous devez également rediriger les entrées.
Cela semble être une fonction/un bug lors de l'exécution de l'application externe youre de départ et de ce que j'ai vu jusqu'à présent, il n'est mentionné nulle part ailleurs.
Exemple d'utilisation:
...
Je ne sais pas si quelqu'un est toujours à la recherche d'une solution à cela, mais il est venu à plusieurs reprises pour moi parce que je suis en train d'écrire un outil dans l'Unité à l'appui de certains jeux et en raison de la faible interopérabilité de certains systèmes mono (comme PIA pour la lecture de texte à partir de Word, par exemple), j'ai souvent à écrire des OS (parfois, Windows, parfois MacOS) exécutables et les lancer à partir de Processus.Start().
Le problème est, quand vous lancer un fichier exécutable comme cela, il va tirer dans un autre thread qui bloque votre application principale, provoquant un blocage. Si vous souhaitez fournir une rétroaction utile pour vos utilisateurs pendant ce temps, au-delà de la filature icônes imaginé par votre système d'exploitation, alors vous êtes le genre de baiser. À l'aide d'un flux ne fonctionne pas parce que le fil est toujours bloqué jusqu'à l'exécution des finitions.
La solution que j'ai frappé à, ce qui peut sembler extrême pour certaines personnes, mais je trouve fonctionne très bien pour moi, est d'utiliser les sockets et le multithreading pour définir fiables de manière synchrone les communications entre les deux applications. Bien sûr, cela ne fonctionne que si vous êtes à la création de deux applications. Si non, je pense que vous êtes hors de la chance. ... Je voudrais voir si il fonctionne seulement avec le multithreading, à l'aide d'un traditionnel flux approche, donc si quelqu'un veut essayer et poster les résultats ici, ce serait génial.
De toute façon, voici la solution actuellement en train de travailler pour moi:
Dans la main, ou en appelant à l'application, je fais quelque chose comme ceci:
Voici où j'ai établir le serveur socket:
Voici mon socket gestionnaire pour le fil... notez que vous devrez créer plusieurs threads dans certains cas; c'est pourquoi j'ai que _builderCommThreads Liste de là (je l'ai porté sous de code ailleurs, là où je faisais quelque chose de similaire, mais l'appel de plusieurs instances dans une rangée):
Bien sûr, vous aurez besoin de déclarer certains trucs en haut:
...puis dans le invoquée exécutable, mis en place l'autre extrémité (j'ai utilisé de la statique dans ce cas, vous pouvez utiliser ce que jamais vous le souhaitez):
...Je suis en utilisant ce de lancer un outil en ligne de commande sur Windows qui utilise le PIA trucs à extraire du texte d'un document Word. J'ai essayé le PIA .dll dans l'Unité, mais a couru dans l'interopérabilité des problèmes avec mono. Je suis également de l'utiliser sur MacOS pour appeler des scripts shell de lancement supplémentaire de l'Unité des instances dans batchmode et exécutez l'éditeur de scripts dans ces instances qui de parler de retour de l'outil au cours de cette connexion de socket. C'est génial, parce que je peux maintenant envoyer des commentaires à l'utilisateur, de débogage, de surveiller et de répondre à des étapes précises du processus, et cetera, et cetera.
HTH
J'ai utilisé le CmdProcessor classe décrit ici sur plusieurs projets avec beaucoup de succès. Il semble un peu intimidant au début, mais c'est très facile à utiliser.
De l'essayer.
Laissez-le au-dessus de l'être dans un
thread
.Maintenant pour la mise à jour de la sortie de l'INTERFACE utilisateur,vous pouvez utiliser un
timer
avec deux lignesCela peut vous aider à
Le problème est causé par l'appel de la Processus.WaitForExit méthode. Ce que cela fait, d'après la documentation, est:
Donc, pour éviter le blocage du thread jusqu'à ce que le processus a quitté, le fil de la Processus.Sorti événement gestionnaire de l'objet de Processus, comme ci-dessous. La Sorti de l'événement ne peut se produire que si la valeur de la propriété EnableRaisingEvents est vrai.
Fait de cette façon, vous serez en mesure d'obtenir la sortie de votre processus, alors qu'il est encore en cours d'exécution, via le Processus.OutputDataReceived événement que vous ne le font actuellement. (PS - l'exemple de code sur la page d'un événement aussi fait l'erreur d'utiliser des Processus.WaitForExit.)
Une autre remarque est que vous devez vous assurer que vos Processus d'objet n'est pas nettoyée avant votre Sorti méthode d'incendie. Si votre Processus est initialisé à l'aide d'instruction, cela pourrait être un problème.