Win32 处理command line参数列表
Windows编程,程序传参,参数分析代码
本代码主要是将文件类型参数和非文件类型参数分开。
1 typedef std::vector<const TCHAR*> ParamVector; 2 3 void parseCommandLine(TCHAR * commandLine, ParamVector & paramVector) { 4 //params.erase(params.begin()); 5 //remove the first element, since that is the path of the executable (GetCommandLine does that) 6 //"D:\WinCE\PowerEditor\visual.net\Unicode Debug\bin\notepadPlus_Debug.exe" "D:\My Documents\code.txt" 7 8 TCHAR stopChar = TEXT(' '); 9 if (commandLine[0] == TEXT('\"')) { 10 stopChar = TEXT('\"'); 11 commandLine++; 12 } 13 //after the first quote has been removed 14 //D:\WinCE\PowerEditor\visual.net\Unicode Debug\bin\notepadPlus_Debug.exe" "D:\My Documents\code.txt" 15 16 //while this is not really DBCS compliant, space and quote are in the lower 127 ASCII range 17 while(commandLine[0] && commandLine[0] != stopChar) 18 { 19 commandLine++; 20 } 21 //after the argv[0] has been removed 22 //" "D:\My Documents\code.txt" 23 24 // For unknown reason, the following command : 25 // c:\NppDir>notepad++ 26 // (without quote) will give string "notepad++\0notepad++\0" 27 // To avoid the unexpected behavior we check the end of string before increasing the pointer 28 if (commandLine[0] != '\0') 29 commandLine++; 30 //after the past stopChar has been removed 31 // "D:\My Documents\code.txt" 32 33 //kill remaining spaces 34 while(commandLine[0] == TEXT(' ')) 35 commandLine++; 36 //finaly we got 37 //"D:\My Documents\code.txt" 38 39 bool isFile = checkSingleFile(commandLine); //if the command line specifies only a file, open it as such 40 if (isFile) { 41 paramVector.push_back(commandLine); 42 return; 43 } 44 bool isInFile = false; 45 bool isInWhiteSpace = true; 46 paramVector.clear(); 47 size_t commandLength = lstrlen(commandLine); 48 for(size_t i = 0; i < commandLength; i++) { 49 switch(commandLine[i]) { 50 case '\"': { //quoted filename, ignore any following whitespace 51 if (!isInFile) { //" will always be treated as start or end of param, in case the user forgot to add an space 52 paramVector.push_back(commandLine+i+1); //add next param(since zero terminated generic_string original, no overflow of +1) 53 } 54 isInFile = !isInFile; 55 isInWhiteSpace = false; 56 //because we don't want to leave in any quotes in the filename, remove them now (with zero terminator) 57 commandLine[i] = 0; 58 break; } 59 case '\t': //also treat tab as whitespace 60 case ' ': { 61 isInWhiteSpace = true; 62 if (!isInFile) 63 commandLine[i] = 0; //zap spaces into zero terminators, unless its part of a filename 64 break; } 65 default: { //default TCHAR, if beginning of word, add it 66 if (!isInFile && isInWhiteSpace) { 67 paramVector.push_back(commandLine+i); //add next param 68 isInWhiteSpace = false; 69 } 70 break; } 71 } 72 } 73 //the command line generic_string is now a list of zero terminated strings concatenated, and the vector contains all the substrings 74 }
1 bool checkSingleFile(const TCHAR * commandLine) { 2 TCHAR fullpath[MAX_PATH]; 3 ::GetFullPathName(commandLine, MAX_PATH, fullpath, NULL); 4 if (::PathFileExists(fullpath)) { 5 return true; 6 } 7 8 return false; 9 }