.NET中的对引号和反斜杠 \和一不同的解释规则

2007-12-06  来源:   浏览次数 36
     最近发现在使用.NET开发的命令行工具的对引号和反斜杠 \和一般命令行程序有着不同的解释规则。中国自学编程网 www.zxbc.cn 举例来说,如果你在命令行下输入: 
C:\> tool “C:\Program Files\”
 

实际上传入的参数是C:\Program Files” 。其实这里不仔细看可能发现不了问题。在原来的命令行中,第一个双引号代表一个参数的开始/结束,后面\”因为.NET的解释规则不同,代表实际的双引号,而非参数的开始/结束,因此最后的结果会多出一个双引号,并且缺少一个反斜杠。
内部,CLR使用CommandLineToArgvW来分析程序的命令行分离出各个参数,这个函数有着特殊的解释规则:
<!--[if !supportLists]-->1.     <!--[endif]-->2n个反斜杠后面跟一个双引号代表n个反斜杠
<!--[if !supportLists]-->2.     <!--[endif]-->2n+1个反斜杠后面跟一个双引号代表n个反斜杠加一个”
<!--[if !supportLists]-->3.     <!--[endif]-->N个反斜杠后面不跟双引号直接代表n个反斜杠
这个规则比较绕,用例子的方式来解释就是:
命令行参数实际参数
“C:\Program Files\”C:\Program Files”
“C:\Program Files\\”C:\Program Files\
“C:\Program Files\\\”C:\Program Files\”

因此,正确的方式是第二个,也就是”C:\Program Files\\”。
 
事实上,CLR内部并没有直接调用CommandLineToArgvw,而是直接实现了一个有着同等功能的函数SegmentCommandLine。在Rotor的源代码中可以找到它的实现,位于sscli20\clr\src\utilcode\util.cpp。CLR的主函数_CorExeMain在执行主函数之前会调用CorCommandLine::SetArgvW,这个函数会调用SegmentCommandLine来分析命令行(经过简化):
 
// Set argvw from command line
/* static */
HRESULT CorCommandLine::SetArgvW(LPCWSTR lpCommandLine)
{

 
    HRESULT hr = S_OK;
if(!m_ArgvW) {
    // 分析命令行
        m_ArgvW = SegmentCommandLine(lpCommandLine, &m_NumArgs);
 
        // CLR特有的命令行处理,主要是和ClickOnce有关的
        if (m_ArgvW)
            hr = ParseCor();
        else
            hr = E_OUTOFMEMORY;
    }
 
    return hr;
}
 

 
真正在执行Main主函数的时候,ClassLoader::RunMain函数则会调用CorCommandLine::GetArgvW获得之前分析得到的参数列表,并创建对应的托管String数组并传递给Main(经过简化):

本新闻共7页,当前在第1页  1  2  3  4  5  6  7  

相关主题:

网友评论