获取命令行参数的各种变化

来源:互联网 发布:php导出excel表格 编辑:程序博客网 时间:2024/06/02 06:29

常,在VC++中获取命令行参数的有如下几种方式:

 

在控制台程序中:

C++运行时库通过入口函数main传递进来的参数int argc 和 char* argv[]。其中第二个参数将一个完整的命令行分割成指向各参数的字符串指针数组,数组中的每一个元素是一个指向参数的字符串指针。其中, argv[0] 指向应用程序名自身。

如果想获得像窗口形式的完整命令行参数CmdLine的话,可以调用API GetCommandLine() 获得。

 

在窗口程序中:

C++运行时库通过入口函数WinMain传递进来的参数LPTSTR pszCmdLine。pszCmdLine是一个完整的命令行参数,包含应用程序名自身。

如果想获得像控制台形式的被分割的命令行参数指针数组的话。可以使用如下代码获得:

[cpp] view plaincopy
  1. //C++ code  
  2. pszCmdLineW = GetCommandLineW();  
  3. argv = CommandLineToArgvW(pszCmdLineW, &argc);  
  4. if (argv != NULL) LocalFree(argv);  

需要注意的是, CommandLineToArgvW只有Unicode的版本,因此省略第二行的代码,而直接将入口函数中提供的参数lpCmdLine传给 CommandLineToArgvW 可能会存在问题,这取决于项目使用的字符集属性,幸好从 VS2005 开始,项目默认使用的字符集就是 Unicode!

 

然而,在实际使用命令行参数,其实并不像如上所述那么简单,还有几个不确定的因素会导致获得的命令行参数发生变化。

 

首先,给出三个测试程序, ConApp 是一个控制台程序,WinApp 是一个窗口程序,这两个程序在内部将获取命令行参数并进行显示,AppCaller是另外一个控制台程序,它将分几次调用 ConApp 和 WinApp ,并为它们传递不同的参数。

测试步骤为:

AppCaller创建ConApp 和 WinApp 子进程,并在控制台上输出传给 ConApp 和 WinApp 的参数,然后等待子进程结束。 ConApp 和 WinApp 显示命令行参数后返回, AppCaller再次调用 ConApp 和 WinAPP 并传递其他参数。

 

三个程序的代码为:

WinApp:

[cpp] view plaincopy
  1. //C++ code  
  2. //Win32 project.  
  3. //WinApp.cpp  
  4.   
  5. #include <Windows.h>  
  6. #include <tchar.h>  
  7. #include <strsafe.h>  
  8. #include <stdarg.h>  
  9.   
  10. //使用XP风格的控件。  
  11. #if defined _M_IX86  
  12. #pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'/"")  
  13. #endif  
  14.   
  15. //函数前导声明。  
  16. HRESULT FormatTextW(WCHAR **, size_t *, LPCWSTR, ...);  
  17. HRESULT AppendTextW(WCHAR **, size_t *, LPCWSTR);  
  18. HRESULT AppendMemHexW(WCHAR **, size_t *, LPBYTEint);  
  19.   
  20. int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,  
  21.     LPTSTR lpCmdLine, int nCmdShow)  
  22. {  
  23.     int argc = 0;  
  24.     int chLen = 0;  
  25.     size_t bufLen = 0;  
  26.     HRESULT hr = S_OK;  
  27.     LPWSTR pszCmdLineW = NULL;  
  28.     LPWSTR *argv = NULL;  
  29.     WCHAR szText[1024] = { 0 };  
  30.     LPWSTR pCur = NULL;  
  31.   
  32.     pszCmdLineW = GetCommandLineW();  
  33.     argv = CommandLineToArgvW(pszCmdLineW, &argc);  
  34.   
  35.     //对命令行参数进行一些格式化,存储到szText中,最后通过MessageBox进行显示。  
  36.     bufLen = _countof(szText);  
  37.     pCur = szText;  
  38.     if (SUCCEEDED(  
  39.         hr = FormatTextW(&pCur, &bufLen, L"GetCommandLineW=%s", pszCmdLineW)  
  40.         ) && SUCCEEDED(  
  41.         hr = AppendMemHexW(&pCur, &bufLen, (LPBYTE)pszCmdLineW,  
  42.         wcslen(pszCmdLineW)*sizeof(WCHAR))  
  43.         ) && SUCCEEDED(  
  44.         hr = AppendTextW(&pCur, &bufLen, L"/r/n")  
  45.         ) && SUCCEEDED(  
  46.         hr = AppendTextW(&pCur, &bufLen, L"CommandLineToArgvW:/r/n")  
  47.         ) && SUCCEEDED(  
  48.         hr = FormatTextW(&pCur, &bufLen, L"argc=%d/r/nargv:/r/n", argc)))  
  49.     {  
  50.         for (int i = 0; i < argc; i++)  
  51.         {  
  52.             hr = FormatTextW(&pCur, &bufLen, L"[#%u]%s", i, argv[i]);  
  53.             if (FAILED(hr)) break;  
  54.             hr = AppendMemHexW(&pCur, &bufLen, (LPBYTE)argv[i],  
  55.                 wcslen(argv[i])*sizeof(WCHAR));  
  56.             if (FAILED(hr)) break;  
  57.         }  
  58.     }  
  59.   
  60.     if (argv != NULL) LocalFree(argv);  
  61.   
  62.     if ((SUCCEEDED(hr)) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))  
  63.     {  
  64.         MessageBoxW(NULL, szText, L"Win App", MB_OK | MB_ICONINFORMATION);  
  65.     }  
  66.   
  67.     return 0;  
  68. }  
  69.   
  70. //格式化文本到缓冲区。  
  71. HRESULT FormatTextW(WCHAR **ppBuf, size_t *pBufLen, LPCWSTR pszFormat, ...)  
  72. {  
  73.     va_list argList;  
  74.     va_start(argList, pszFormat);  
  75.     int chLen = 0;  
  76.     HRESULT hr = S_OK;  
  77.   
  78.     hr = StringCchVPrintfExW(*ppBuf, *pBufLen, ppBuf, pBufLen,  
  79.         STRSAFE_IGNORE_NULLS, pszFormat, argList);  
  80.     va_end(argList);  
  81.   
  82.     return hr;  
  83. }  
  84.   
  85. //添加文本到缓冲区。  
  86. HRESULT AppendTextW(WCHAR **ppBuf, size_t *pBufLen, LPCWSTR pszText)  
  87. {  
  88.     return StringCchCatExW(*ppBuf, *pBufLen, pszText, ppBuf, pBufLen,  
  89.         STRSAFE_IGNORE_NULLS);  
  90. }  
  91.   
  92. //添加16进制形式的内存字节到缓冲区。  
  93. HRESULT AppendMemHexW(WCHAR **ppBuf, size_t *pBufLen, LPBYTE pMem, int cbLen)  
  94. {  
  95.     HRESULT hr = S_OK;  
  96.     WCHAR sz[512] = { 0 };  
  97.   
  98.     hr = StringCchCatEx(*ppBuf, *pBufLen, L"(", ppBuf, pBufLen,  
  99.         STRSAFE_IGNORE_NULLS);  
  100.   
  101.     for (int i = 0; i < cbLen; i += 2)  
  102.     {  
  103.         hr = StringCchPrintfEx(*ppBuf, *pBufLen, ppBuf, pBufLen,  
  104.             STRSAFE_IGNORE_NULLS, L"%02x%02x", pMem[i], pMem[i+1]);  
  105.         if (FAILED(hr)) break;  
  106.         if (i != (cbLen - 2))  
  107.         {  
  108.             hr = StringCchCatEx(*ppBuf, *pBufLen, L" ", ppBuf, pBufLen,  
  109.                 STRSAFE_IGNORE_NULLS);  
  110.             if (FAILED(hr)) break;  
  111.         }  
  112.     }  
  113.   
  114.     if (SUCCEEDED(hr))  
  115.     {  
  116.         hr = StringCchCatEx(*ppBuf, *pBufLen, L")/r/n", ppBuf, pBufLen,  
  117.             STRSAFE_IGNORE_NULLS);  
  118.     }  
  119.     return hr;  
  120. }  
  121.   
  122. //end of WinApp.cpp  

 

ConApp:

[cpp] view plaincopy
  1. //C++ code  
  2. //Console project.  
  3. //ConApp.cpp  
  4.   
  5. #include <stdio.h>  
  6. #include <tchar.h>  
  7. #include <Windows.h>  
  8.   
  9. //函数前导声明。  
  10. void PrintMem(LPBYTEint);  
  11.   
  12. int _tmain(int /*argc*/, _TCHAR* /*argv[]*/)  
  13. {  
  14.     int argc = 0;  
  15.     LPWSTR pszCmdLineW = GetCommandLineW();  
  16.     LPWSTR *argv = CommandLineToArgvW(pszCmdLineW, &argc);  
  17.   
  18.     //对命令行参数进行一些格式化,然后输出到控制台上。  
  19.     wprintf(L"GetCommandLineW=%s", pszCmdLineW);  
  20.     PrintMem((LPBYTE)pszCmdLineW, wcslen(pszCmdLineW)*sizeof(WCHAR));  
  21.     _tprintf(_T("/r/n"));  
  22.   
  23.     _tprintf(_T("CommandLineToArgvW:/r/n"));  
  24.     _tprintf(_T("argc=%d/r/nargv:/r/n"), argc);  
  25.     for (int i = 0; i < argc; i++)  
  26.     {  
  27.         wprintf(L"[#%u]%s", i, argv[i]);  
  28.         PrintMem((LPBYTE)argv[i], wcslen(argv[i])*sizeof(WCHAR));  
  29.     }  
  30.     return 0;  
  31. }  
  32.   
  33. //输出16进制形式的内存字节。  
  34. void PrintMem(LPBYTE pMem, int len)  
  35. {  
  36.     _puttchar(_T('('));  
  37.   
  38.     for (int i = 0; i < len; i += 2)  
  39.     {  
  40.         //内存字节是 Unicode 字符集数据,一次打印两个字节。  
  41.         _tprintf(_T("%02x%02x"), pMem[i], pMem[i+1]);  
  42.         if (i != (len - 2))  
  43.         {  
  44.             _puttchar(_T(' '));  
  45.         }  
  46.     }  
  47.     _tprintf(_T(")/r/n"));  
  48. }  
  49.   
  50. //end of ConApp.cpp  

 

AppCaller:

[c-sharp] view plaincopy
  1. //C++ code  
  2. //Console project.  
  3. //AppCaller.cpp  
  4.  
  5. #include <stdio.h>  
  6. #include <tchar.h>  
  7. #include <Windows.h>  
  8.   
  9. //函数前导声明。  
  10. void CallApp(LPCTSTR, LPTSTR);  
  11.   
  12. int _tmain(int argc, _TCHAR* argv[])  
  13. {  
  14.     //假设 WinApp.exe 和 CmdApp.exe 在当前目录中。  
  15.     LPCTSTR pszWinApp = _T("WinApp.exe");  
  16.     LPCTSTR pszConApp = _T("ConApp.exe");  
  17.     TCHAR szCmdLine1[] = { _T("/t123") };  
  18.     TCHAR szCmdLine2[] = { _T(" 123") };  
  19.     TCHAR szWinCmdLine1[] = { _T("/"WinApp.exe/"") };  
  20.     TCHAR szWinCmdLine2[] = { _T("WinApp.exe") };  
  21.     TCHAR szConCmdLine1[] = { _T("/"ConApp.exe/"") };  
  22.     TCHAR szConCmdLine2[] = { _T("ConApp.exe") };  
  23.       
  24.     //窗口程序测试。  
  25.     CallApp(pszWinApp, NULL);  
  26.     CallApp(pszWinApp, szWinCmdLine1);  
  27.     CallApp(pszWinApp, szWinCmdLine2);  
  28.     CallApp(pszWinApp, szCmdLine1);  
  29.     CallApp(pszWinApp, szCmdLine2);  
  30.       
  31.     //控制台程序测试。  
  32.     CallApp(pszConApp, NULL);  
  33.     CallApp(pszConApp, szConCmdLine1);  
  34.     CallApp(pszConApp, szConCmdLine2);  
  35.     CallApp(pszConApp, szCmdLine1);  
  36.     CallApp(pszConApp, szCmdLine2);  
  37.       
  38.     return 0;  
  39. }  
  40.   
  41. void CallApp(LPCTSTR pszApp, LPTSTR pszCmdLine)  
  42. {  
  43.     static int c = 0;  
  44.     BOOL bRet = FALSE;  
  45.     STARTUPINFO si = { sizeof(si) };  
  46.     PROCESS_INFORMATION pi = { 0 };  
  47.   
  48.     _tprintf(_T("------------------------------------------/r/n/r/n"));  
  49.     _tprintf(_T("<CASE %d>/r/n/r/n"), c);  
  50.     c++;  
  51.     _tprintf(_T("pszCmdLine -- %s/r/n"),  
  52.         pszCmdLine == NULL ? _T("NULL") : pszCmdLine);  
  53.     bRet = CreateProcess(pszApp, pszCmdLine, NULL, NULL, FALSE, 0,  
  54.         NULL, NULL, &si, &pi);  
  55.     if (bRet != FALSE)  
  56.     {  
  57.         if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE))  
  58.         {  
  59.             CloseHandle(pi.hThread);  
  60.             CloseHandle(pi.hProcess);  
  61.         }  
  62.     }  
  63.     _tprintf(_T("/r/n------------------------------------------/r/n"));  
  64. }  
  65.   
  66. //end of AppCaller.cpp  
0 0
原创粉丝点击