Приложение, запущенное процессом.Функция Start() не получает аргументов
-
20-12-2019 - |
Вопрос
Используя C #, я пытаюсь передать аргументы командной строки новому процессу, используя Process .Start():
string path = @"C:\Demo\Demo.exe";
string arguments = "one two three";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = path,
Arguments = arguments
};
var process = Process.Start(startInfo);
Мое приложение на C Demo.exe просто повторяет аргументы командной строки:
int main( int argc, char *argv[] )
{
int count=0;
// Display each command-line argument.
printf( "\nCommand-line arguments:\n" );
for( count = 0; count < argc; count++ )
printf( " argv[%d] %s\n", count, argv[count] );
while(1);
}
Если я запускаю свое приложение с cmd.exe, я получаю разумный результат:
Command-line arguments:
argv[0] Demo.exe
argv[1] one
argv[2] two
argv[3] three
Когда я использую приложение C #, единственное, что я получаю, - это аргумент path в argv[0]:
Command-line arguments:
argv[0] C:
Диспетчер задач показывает аргументы командной строки для каждого метода запуска Demo.exe:
Почему мое приложение на C не получает аргументы командной строки от приложения на C #?
Редактировать @hvd предложил мне использовать GetCommandLine().Вот код и результат этого:
char* ar = GetCommandLine();
printf( "\nGetCommandLine arguments:\n" );
printf(" %s", ar);
Выходной сигнал:
GetCommandLine arguments:
"C:
Возможно ли, что приложение C получает аргументы в виде одной строки, но игнорирует все после первого \ в пути?
Редактировать: Я добавил ответ ниже.Это обходной путь, но я не уверен в причине моей проблемы.
Решение
Я смог воспроизвести вашу проблему.У меня не было доступа к C, поэтому я использовал C ++ в Visual Studio 2013.Похоже, что C # использует СтартИнфо передает аргументы как Юникод символов, поэтому первый байт отличен от нуля, в то время как 2-й байт, вероятно, равен 0 битам, что приводит к отображению только первого символа, поскольку это указывает на символ завершения строки.Когда я использовал printf, это не сработало, мне пришлось использовать _tprintf, чтобы увидеть, что передается.И printf не обрабатывает Юникод.Printf не только не обрабатывает это, но и ваша программа на языке Си при заполнении argv не будет переводить Юникод к строке, использующей символы в 1 байт.В то время как TCHAR (широкий символ) и tprintf в C ++ работают так же, как и C # изначально.
Итак, когда вы сделали это другим способом, используя "cmd.exe" позвонить "/C Demo.exe раз, два, три" cmd не передавал строку как Юникод.Это моя гипотеза, учитывая результаты, которые я получаю.
Связанный с этим вопрос о StackOverflow
Код на C ++, который правильно отображал аргументы (tprintf) и неправильно (printf)
#include "stdafx.h"
#include "string.h"
int _tmain(int argc, _TCHAR* argv[])
{
int count=0;
// Display each command-line argument.
printf( "\nCommand-line arguments:\n" );
for( count = 0; count < argc; count++ )
//Correct. This statement worked, displaying the arguments
//_tprintf( _T(" argv[%d] %s\n"), count, argv[count] );
//Incorrect. Displayed only the first character of each argument
//printf( " argv[%d] %s\n", count, argv[count] );
getchar();
return 0;
}
Это код на C #, который вызвал это
namespace ProcessPassArguments
{
class Program
{
static void Main(string[] args)
{
string path = @"C:\Temp\Demo.exe";
string arguments = "one two three";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = path,
Arguments = arguments
};
var process = Process.Start(startInfo);
}
}
}
Исключительно в информационных целях C #, вызывающий C #, также работал.Опять же, предполагаемая причина заключается в том, что C # передает аргументы вашей программе на C как Юникод Персонажи.
Вызывается код на C #, который работает как запрограммированный целевой объект.
namespace Demo
{
class Program
{
static void Main(string[] args)
{
int i = 0;
foreach (string arg in args)
{
i++;
Console.WriteLine("Argument {0}: {1}", i, arg);
}
Console.ReadLine();
}
}
}
Другие советы
Я вернулся к этому сегодня и сработал обходной путь.Я не понимаю, почему моя оригинальная попытка не работает.
Вот разница в командной строке между типом Demo.exe и «Demo.exe».
C:\Users\me\Desktop\Work\Builds\Win32>Demo.exe one two three
There are 4 arguments.
Command-line arguments:
argv[0]: Demo.exe
argv[1]: one
argv[2]: two
argv[3]: three
C:\Users\me\Desktop\Work\Builds\Win32>"Demo.exe" one two three
There are 1 arguments.
Command-line arguments:
argv[0]: Demo.exe
.
Процесс.Start () Вызов, казалось, выполняет разнообразие «Demo.exe».
не работает:
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = @"Demo.exe",
WorkingDirectory = @"C:\Users\me\Desktop\Work\Builds\Win32",
Arguments = "one two three"
};
var process = Process.Start(startInfo);
There are 1 arguments.
Command-line arguments:
argv[0]: C:
.
работает:
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = @"C:\Users\me\Desktop\Work\Builds\Win32",
Arguments = "/C Demo.exe one two three"
};
var process = Process.Start(startInfo);
There are 4 arguments.
Command-line arguments:
argv[0]: Demo.exe
argv[1]: one
argv[2]: two
argv[3]: three
.
У кого-нибудь есть идеи, почему первый метод не работает?
попробуйте это
Arguments = "\"arg1\" \"arg2\" \"arg3\"";
.