CreateProcess et les arguments de ligne de commande
Info De Base: Windows 7, Visual C++ 2010 Express
Problème: CreateProcess() conserve son retour avec "Invalid argument de ligne de commande'
Explication: je suis en train d'écrire un morceau de code qui appelle à des programmes externes à l'aide de la Windows API CreateProcess. J'ai reçu l'appel à travailler avec un programme externe jusqu'à présent:
if( !CreateProcess( "C:\\Temp\\convert.exe",
t_str, //Arguments
...
}
//where t_str is " C:\\img1.jpeg C:\\img1.pgm" (ImageMagick if you're wondering).
Cela fonctionne parfaitement, même avec la quantité de données modificateur j'ai fait pour pousser le tout dans le Windows des chaînes et des pointeurs. J'ai donc copié l'ensemble de la déformation de la fonction CreateProcess() pour un autre appel à un autre programme externe:
if( !CreateProcess( "C:\\Temp\\sift.exe",
t_str2, //Arguments
...
}
//where t_str2 is ` < C:\\img1.pgm > C:\\img1.key`
Fondamentalement, quelque chose de très similaire, mais avec tous les noms de variable changé (depuis que j'ai ces deux appels de course de série). Et c'est là que le problème, ce n'est pas l'exécuter, et, au lieu de cela, l'affiche "Invalid argument de ligne de commande: < C:\img1.pgm". Bien sûr, cette commande fonctionne très bien dans l'invite de commande, mais pas dans mon code.
Je suis passé t_str2 à quelque chose d'autre un peu moins compliqué(vu que je sais comment sift.exe travaille) et j'obtiens le même résultat. La même chose arrive quand je lance juste des eipd et de ne pas convertir.
Question: Ce qui pourrait être à l'origine de ce problème? Que pourrais-je faire pour déboguer ce problème? Toutes les suggestions sur les solutions de rechange pour les méthodes que j'utilise? Toute aide est appréciée. Je peux fournir plus de code, mais C'est assez simple, et pas beaucoup pourrait aller mal avec elle.
cmd.exe
avec des paramètres /c c:\temp\sift.exe < c:\img1.pmg > c:\img1.key
?OriginalL'auteur user850275 | 2011-12-27
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas utiliser la ligne de commande opérateurs de redirection avec
CreateProcess()
directement. Vous devez vous frayer un exemple de cmd.exe et de transmettre les opérateurs de la place, par exemple:Où
t_str2
est"/C C:\\Temp\\sift.exe < C:\\img1.pgm > C:\\img1.key"
. Le chemin d'accès réel cmd.exe peut être déterminé par la lecture de la%COMSPEC%
variable d'environnement.OriginalL'auteur Remy Lebeau
Dans le deuxième exemple que vous essayez d'utiliser l'entrée standard et la sortie des redirections, qui sont les notations de l'application en ligne de commande. Mais ils ne sont pas valides arguments du programme. Si vous souhaitez utiliser la redirection, vous devez ouvrir les tuyaux et la main de lire et écrire à partir de/à l'entrée/sortie de fichiers. Ici vous pouvez trouver un exemple sur la façon de mettre en œuvre pthe processus de création avec entrée/sortie des redirections.
CreateProcess
n'est pas une ligne de commande du processeur.Je n'ai pas signifiait que
CreateProcess
est un interpréteur de lignes de commande. J'ai voulu dire qu'il ne peut pas accepter les redirections comme arguments d'un processus. Et si l'on wats à utiliser les redirections, il doit explicitement de fournir le code correspondant.Je suis d'accord, j'étais en soulignant pourquoi il ne peut pas accepter les redirections comme arguments...parce que c'est quelque chose de la ligne de commande de Windows processeur n'.
Ahhh, je vois. Qui aurait plus de sens. C'est ma première fois de passer aux choses sérieuses avec la programmation de Windows. Merci pour l'aperçu
OriginalL'auteur Eugene
CreateProcess
a quelques ennuyeux de pièges, et les plus âgés des réponses à travers Stack Exchange peut rendre ce processus un peu gênant si vous n'êtes pas aussi le référencement de la documentation officielle.CreateProcess
est, pour la plupart, en option, ce qui est vraiment bizarre pour un premier paramètre. Si vous ne souhaitez pas spécifier, utilisezNULL
, sinon, vous devriez lire le très spécifiques la documentation sur la façon d'utiliser le paramètre 1 quand ne pas le mettre àNULL
.NULL
, l'application doit être la première partie de paramètre 2.Encore merci à Remy pour nettoyer le comportement bizarre sur ma première réponse.
Cet exemple de code ne nécessite qu'une base compilateur VC++ sur Windows et la capacité de prendre et de stocker un fichier sur le Bureau qui sera inauguré par le bloc-notes.
Si ce n'est pas pratique, n'hésitez pas à utiliser
%temp%
ou à un autre endroit pour placer le fichier de test. L'application va s'exécuter jusqu'à ce que vous fermez notepad.exe. Cette traite également d'obtenir et de retourner le code de sortie. Si vous ne voulez pas à s'exécuter indéfiniment, jusqu'à la sortie, vous aurez besoin de mettre à jour leWaitForSingleObject
ligne.CreateProcess()
va analyser le fichier EXE pour exécuter à partir de la deuxième paramètre. C'est la plus facile et la plus courante scénario, et est entièrement documenté.CreateProcess(NULL, "C:\\Windows\\System32\\cmd.exe <params>", ...);
Nice, @RemyLebeau! Je vais le mettre à jour.
Votre
(char*)
transtypage est redondant lors de la compilation pour la norme ANSI/MBCS, et, se cache un moteur d'exécution d'un bug lors de la compilation pour l'Unicode. Suffit de s'en débarrasser complètement. Dans ce dernier cas, vous ne pouvez pas passer un littéral pour le paramètre de toute façon (à l'exécution de crash), de sorte que vous devez copier le chemin d'accès à un localchar[]
/wchar_t[]
tableau en premier et ensuite passer à la place.Wow! Quel vilain petit écueil 🙁 mise à Jour maintenant! ^_^ Tyvm, @RemyLebeau!
OriginalL'auteur kayleeFrye_onDeck