Приложение, запущенное процессом.Функция Start() не получает аргументов

StackOverflow https://stackoverflow.com//questions/24000793

Вопрос

Используя 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:enter image description here

Почему мое приложение на 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\"";
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top