Process.Start()启动的应用程序没有得到参数

Gre*_*bon 11 c# processstartinfo process.start

使用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);
Run Code Online (Sandbox Code Playgroud)

我的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);
}
Run Code Online (Sandbox Code Playgroud)

如果我从cmd.exe启动我的应用程序,我得到合理的输出:

Command-line arguments:
 argv[0]   Demo.exe
 argv[1]   one
 argv[2]   two
 argv[3]   three
Run Code Online (Sandbox Code Playgroud)

当我使用C#应用程序时,我唯一得到的是argv [0]中的path参数:

Command-line arguments:
  argv[0]   C:
Run Code Online (Sandbox Code Playgroud)

任务管理器显示启动Demo.exe的每种方法的命令行参数: 在此输入图像描述

为什么我的C应用程序不接收来自C#应用程序的命令行参数?

编辑 @hvd建议我使用GetCommandLine().这是代码和结果:

char* ar = GetCommandLine();
printf( "\nGetCommandLine arguments:\n" );
printf("  %s", ar);
Run Code Online (Sandbox Code Playgroud)

输出:

GetCommandLine arguments:
  "C:
Run Code Online (Sandbox Code Playgroud)

是否有可能C应用程序将args作为一个字符串接收,但忽略了路径中第一个\之后的所有内容?

编辑:我在下面添加了答案.这是一种解决方法,但我不确定我的问题的原因.

Gre*_*bon 5

我今天回到了这个问题,并有一个解决方法。我不明白为什么我最初的尝试没有奏效。

这是键入 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
Run Code Online (Sandbox Code Playgroud)

Process.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:
Run Code Online (Sandbox Code Playgroud)

是否有效:

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
Run Code Online (Sandbox Code Playgroud)

有没有人知道为什么第一种方法不起作用?


Cod*_*Org 4

我能够重现您的问题。我无法访问 C,因此我在 Visual Studio 2013 中使用了 C++。看来使用StartInfo 的C#将参数作为Unicode字符传递,因此第一个字节非零,而第二个字节可能是 0 位,导致仅显示第一个字符,因为它指示字符串终止字符。当我使用 printf 时它不起作用,我必须使用 _tprintf 来查看传递的内容。并且 printf 不处理Unicode。printf 不仅不能处理它,您的 C 程序在填充argv时也不会将Unicode转换为使用 1 字节字符的字符串。C++ 中的 TCHAR(宽字符)和 tprintf 是这样做的,C# 本身也是如此。

因此,当您以另一种方式执行此操作时,使用“cmd.exe”调用“/C Demo.exe 一二三” cmd 不会将字符串作为Unicode传递。鉴于我得到的结果,这是我的假设。

StackOverflow 上的相关问题

正确显示参数(tprintf)和错误显示参数 (printf)的 C++ 代码

#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;
}
Run Code Online (Sandbox Code Playgroud)

这是调用它的 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

仅供参考,C# 调用 C# 也可以。再次怀疑的原因是 C# 将参数作为Unicode字符传递给 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();
        }

    }
}
Run Code Online (Sandbox Code Playgroud)