Application started by Process.Start() isn't getting arguments

I've gotten back to this today and have a workaround working. I don't understand why my original attempt didn't work.

Here is the difference on the command line between typing Demo.exe and “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

The Process.Start() call seemed to be doing the “Demo.exe” variety.

Doesn’t work:

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:

Does work:

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

Does anyone have any ideas why the first method doesn't work?


I was able to reproduce your issue. I didn't have access to C, so I used C++ in Visual Studio 2013. It appears that C# using StartInfo passes the arguments as Unicode characters, so the first byte is non-zero, while the 2nd byte is likely 0 bits resulting in displaying only the first character since that indicates the string termination character. When I used printf it did not work, I had to use _tprintf to see what is passed. And printf does not handle Unicode. Not only does printf not handle it, your C program when populating argv will not translate Unicode to a string using 1 byte characters. While TCHAR (wide char) and tprintf in C++ does, as does C# natively.

So, when you did it the other way, using "cmd.exe" to call "/C Demo.exe one two three" cmd was not passing the string as Unicode. That's my hypothesis, given the results I am getting.

Related Question on StackOverflow

  • Does Process.StartInfo.Arguments support a UTF-8 string?

The C++ code that displayed the Arguments correctly (tprintf) and incorrectly (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;
}

This is the C# code that called it

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);
        }
    }
}

For informational purposes only, C# calling the C# also worked. Again the suspected cause is that C# is passing the arguments to your C program as Unicode Characters.

The C# code that works as the target programmed called.

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();
        }

    }
}