C#的命令行参数

时间:2022-12-02 14:28:33

      这一周尝试着用C#写了两个后台程序,主程序用CreateProcess()传递命令行参数并创建进程。在实现的过程中,碰到了一个问题,命令行参数中如果带有空格该如何处理。一直认为,命令行中的空格用作参数的分隔符。如果参数内部有空格,该怎么办呢?譬如命令行的参数为“祝福 张学友 \Program Files\1 2 3.lrc”。

      刚开始写后台程序时,没考虑到这个问题。后来ZWF在使用时问起,才注意到。经过商量,决定自己定义一个命令行格式,用|作为分隔符。将“祝福 张学友 \Program Files\1 2 3.lrc”改为“祝福|张学友|\Program Files\1 2 3.lrc”。在后台程序中,首先将所有的参数合并,然后再通过分隔符|解析各个字段,代码如下:

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Windows.Forms;

namespace  ConsoleApplication1
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            String temp 
=   "" ;
            
string  song, singer, path;
            
int  head, tail;
            
//  合并命令行参数
             for  ( int  i  =   0 ; i  <  args.Length; i ++ )
            {
                MessageBox.Show(args[i]);
                temp 
+=  args[i];
                temp 
+=   "   " ;
            }
            MessageBox.Show(temp);
            
try
            {
                
//  解析合并后的命令行
                head  =  temp.IndexOf( ' | ' 0 );
                song 
=  temp.Substring( 0 , head);
                MessageBox.Show(song);
                head 
+=   1 ;
                tail 
=  temp.IndexOf( ' | ' , head);
                singer 
=  temp.Substring(head, tail  -  head);
                MessageBox.Show(singer);
                path 
=  temp.Substring(tail  +   1 );
                MessageBox.Show(path);
            }
            
catch {}
        }
    }
}

       主程序是用C++写的,代码如下:

int  _tmain( int  argc, _TCHAR *  argv[])
{
    TCHAR szCMD[MAX_PATH];
    PROCESS_INFORMATION pi;
    STARTUPINFO sii;

    memset(
& sii,  0 sizeof (sii));
    sii.cb 
=   sizeof (sii);
    sii.wShowWindow 
=  SW_SHOW;
    sii.dwFlags 
=  STARTF_USESHOWWINDOW;

    
//  自定义格式的命令行参数
    wcscpy(szCMD, L "  祝福|张学友|\\Program Files\\1 2 3.lrc " );
    
//  使用系统支持的命令行参数
    
// wcscpy(szCMD,L" 祝福 张学友 \"\\Program Files\\1 2 3.lrc\"");

    CreateProcess(_T(
" .\\ConsoleApplication1.exe " ), szCMD,
        NULL, NULL, 
0 0 , NULL, NULL,  & sii,  & pi);

    
return   0 ;
}

       注意,wcscpy(szCMD, L" 祝福|张学友|\\Program Files\\1 2 3.lrc");中祝福前必须留一个空格,否则会导致后台程序接收的命令行不完整。关于这一点,请参考《C++和C#程序之间命令行参数传递和接收》,博主整理的非常细致。MSDN中有关C#命令行参数的说明,Main() 和命令行参数(C# 编程指南),其中提到了“与 C 和 C++ 不同,C#程序的名称不会被当作第一个命令行参数”。

      虽然通过自定义命令行的方式,解决了命令行参数本身带有空格的问题,但总感觉有点怪。这是参数不多,如果参数多了怎么办?按理来说,命令行参数的解析规则不能这么简单。在MSDN中查了一下,有其具体的解析规则Parsing C Command-Line Arguments。其中第一个示例就是解决命令行参数中带有空格的问题,只要将该参数放在一对双引号内就可以了。所以,将“祝福 张学友 \Program Files\1 2 3.lrc”改成“ 祝福 张学友 \"\Program Files\1 2 3.lrc\"”即可。通过实验证明,这种方法可行,且简单方便。