获取命令行参数的各种变化
来源:互联网 发布:php导出excel表格 编辑:程序博客网 时间:2024/06/02 06:29
常,在VC++中获取命令行参数的有如下几种方式:
在控制台程序中:
C++运行时库通过入口函数main传递进来的参数int argc 和 char* argv[]。其中第二个参数将一个完整的命令行分割成指向各参数的字符串指针数组,数组中的每一个元素是一个指向参数的字符串指针。其中, argv[0] 指向应用程序名自身。
如果想获得像窗口形式的完整命令行参数CmdLine的话,可以调用API GetCommandLine() 获得。
在窗口程序中:
C++运行时库通过入口函数WinMain传递进来的参数LPTSTR pszCmdLine。pszCmdLine是一个完整的命令行参数,包含应用程序名自身。
如果想获得像控制台形式的被分割的命令行参数指针数组的话。可以使用如下代码获得:
- //C++ code
- pszCmdLineW = GetCommandLineW();
- argv = CommandLineToArgvW(pszCmdLineW, &argc);
- 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:
- //C++ code
- //Win32 project.
- //WinApp.cpp
- #include <Windows.h>
- #include <tchar.h>
- #include <strsafe.h>
- #include <stdarg.h>
- //使用XP风格的控件。
- #if defined _M_IX86
- #pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'/"")
- #endif
- //函数前导声明。
- HRESULT FormatTextW(WCHAR **, size_t *, LPCWSTR, ...);
- HRESULT AppendTextW(WCHAR **, size_t *, LPCWSTR);
- HRESULT AppendMemHexW(WCHAR **, size_t *, LPBYTE, int);
- int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
- LPTSTR lpCmdLine, int nCmdShow)
- {
- int argc = 0;
- int chLen = 0;
- size_t bufLen = 0;
- HRESULT hr = S_OK;
- LPWSTR pszCmdLineW = NULL;
- LPWSTR *argv = NULL;
- WCHAR szText[1024] = { 0 };
- LPWSTR pCur = NULL;
- pszCmdLineW = GetCommandLineW();
- argv = CommandLineToArgvW(pszCmdLineW, &argc);
- //对命令行参数进行一些格式化,存储到szText中,最后通过MessageBox进行显示。
- bufLen = _countof(szText);
- pCur = szText;
- if (SUCCEEDED(
- hr = FormatTextW(&pCur, &bufLen, L"GetCommandLineW=%s", pszCmdLineW)
- ) && SUCCEEDED(
- hr = AppendMemHexW(&pCur, &bufLen, (LPBYTE)pszCmdLineW,
- wcslen(pszCmdLineW)*sizeof(WCHAR))
- ) && SUCCEEDED(
- hr = AppendTextW(&pCur, &bufLen, L"/r/n")
- ) && SUCCEEDED(
- hr = AppendTextW(&pCur, &bufLen, L"CommandLineToArgvW:/r/n")
- ) && SUCCEEDED(
- hr = FormatTextW(&pCur, &bufLen, L"argc=%d/r/nargv:/r/n", argc)))
- {
- for (int i = 0; i < argc; i++)
- {
- hr = FormatTextW(&pCur, &bufLen, L"[#%u]%s", i, argv[i]);
- if (FAILED(hr)) break;
- hr = AppendMemHexW(&pCur, &bufLen, (LPBYTE)argv[i],
- wcslen(argv[i])*sizeof(WCHAR));
- if (FAILED(hr)) break;
- }
- }
- if (argv != NULL) LocalFree(argv);
- if ((SUCCEEDED(hr)) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- MessageBoxW(NULL, szText, L"Win App", MB_OK | MB_ICONINFORMATION);
- }
- return 0;
- }
- //格式化文本到缓冲区。
- HRESULT FormatTextW(WCHAR **ppBuf, size_t *pBufLen, LPCWSTR pszFormat, ...)
- {
- va_list argList;
- va_start(argList, pszFormat);
- int chLen = 0;
- HRESULT hr = S_OK;
- hr = StringCchVPrintfExW(*ppBuf, *pBufLen, ppBuf, pBufLen,
- STRSAFE_IGNORE_NULLS, pszFormat, argList);
- va_end(argList);
- return hr;
- }
- //添加文本到缓冲区。
- HRESULT AppendTextW(WCHAR **ppBuf, size_t *pBufLen, LPCWSTR pszText)
- {
- return StringCchCatExW(*ppBuf, *pBufLen, pszText, ppBuf, pBufLen,
- STRSAFE_IGNORE_NULLS);
- }
- //添加16进制形式的内存字节到缓冲区。
- HRESULT AppendMemHexW(WCHAR **ppBuf, size_t *pBufLen, LPBYTE pMem, int cbLen)
- {
- HRESULT hr = S_OK;
- WCHAR sz[512] = { 0 };
- hr = StringCchCatEx(*ppBuf, *pBufLen, L"(", ppBuf, pBufLen,
- STRSAFE_IGNORE_NULLS);
- for (int i = 0; i < cbLen; i += 2)
- {
- hr = StringCchPrintfEx(*ppBuf, *pBufLen, ppBuf, pBufLen,
- STRSAFE_IGNORE_NULLS, L"%02x%02x", pMem[i], pMem[i+1]);
- if (FAILED(hr)) break;
- if (i != (cbLen - 2))
- {
- hr = StringCchCatEx(*ppBuf, *pBufLen, L" ", ppBuf, pBufLen,
- STRSAFE_IGNORE_NULLS);
- if (FAILED(hr)) break;
- }
- }
- if (SUCCEEDED(hr))
- {
- hr = StringCchCatEx(*ppBuf, *pBufLen, L")/r/n", ppBuf, pBufLen,
- STRSAFE_IGNORE_NULLS);
- }
- return hr;
- }
- //end of WinApp.cpp
ConApp:
- //C++ code
- //Console project.
- //ConApp.cpp
- #include <stdio.h>
- #include <tchar.h>
- #include <Windows.h>
- //函数前导声明。
- void PrintMem(LPBYTE, int);
- int _tmain(int /*argc*/, _TCHAR* /*argv[]*/)
- {
- int argc = 0;
- LPWSTR pszCmdLineW = GetCommandLineW();
- LPWSTR *argv = CommandLineToArgvW(pszCmdLineW, &argc);
- //对命令行参数进行一些格式化,然后输出到控制台上。
- wprintf(L"GetCommandLineW=%s", pszCmdLineW);
- PrintMem((LPBYTE)pszCmdLineW, wcslen(pszCmdLineW)*sizeof(WCHAR));
- _tprintf(_T("/r/n"));
- _tprintf(_T("CommandLineToArgvW:/r/n"));
- _tprintf(_T("argc=%d/r/nargv:/r/n"), argc);
- for (int i = 0; i < argc; i++)
- {
- wprintf(L"[#%u]%s", i, argv[i]);
- PrintMem((LPBYTE)argv[i], wcslen(argv[i])*sizeof(WCHAR));
- }
- return 0;
- }
- //输出16进制形式的内存字节。
- void PrintMem(LPBYTE pMem, int len)
- {
- _puttchar(_T('('));
- for (int i = 0; i < len; i += 2)
- {
- //内存字节是 Unicode 字符集数据,一次打印两个字节。
- _tprintf(_T("%02x%02x"), pMem[i], pMem[i+1]);
- if (i != (len - 2))
- {
- _puttchar(_T(' '));
- }
- }
- _tprintf(_T(")/r/n"));
- }
- //end of ConApp.cpp
AppCaller:
- //C++ code
- //Console project.
- //AppCaller.cpp
- #include <stdio.h>
- #include <tchar.h>
- #include <Windows.h>
- //函数前导声明。
- void CallApp(LPCTSTR, LPTSTR);
- int _tmain(int argc, _TCHAR* argv[])
- {
- //假设 WinApp.exe 和 CmdApp.exe 在当前目录中。
- LPCTSTR pszWinApp = _T("WinApp.exe");
- LPCTSTR pszConApp = _T("ConApp.exe");
- TCHAR szCmdLine1[] = { _T("/t123") };
- TCHAR szCmdLine2[] = { _T(" 123") };
- TCHAR szWinCmdLine1[] = { _T("/"WinApp.exe/"") };
- TCHAR szWinCmdLine2[] = { _T("WinApp.exe") };
- TCHAR szConCmdLine1[] = { _T("/"ConApp.exe/"") };
- TCHAR szConCmdLine2[] = { _T("ConApp.exe") };
- //窗口程序测试。
- CallApp(pszWinApp, NULL);
- CallApp(pszWinApp, szWinCmdLine1);
- CallApp(pszWinApp, szWinCmdLine2);
- CallApp(pszWinApp, szCmdLine1);
- CallApp(pszWinApp, szCmdLine2);
- //控制台程序测试。
- CallApp(pszConApp, NULL);
- CallApp(pszConApp, szConCmdLine1);
- CallApp(pszConApp, szConCmdLine2);
- CallApp(pszConApp, szCmdLine1);
- CallApp(pszConApp, szCmdLine2);
- return 0;
- }
- void CallApp(LPCTSTR pszApp, LPTSTR pszCmdLine)
- {
- static int c = 0;
- BOOL bRet = FALSE;
- STARTUPINFO si = { sizeof(si) };
- PROCESS_INFORMATION pi = { 0 };
- _tprintf(_T("------------------------------------------/r/n/r/n"));
- _tprintf(_T("<CASE %d>/r/n/r/n"), c);
- c++;
- _tprintf(_T("pszCmdLine -- %s/r/n"),
- pszCmdLine == NULL ? _T("NULL") : pszCmdLine);
- bRet = CreateProcess(pszApp, pszCmdLine, NULL, NULL, FALSE, 0,
- NULL, NULL, &si, &pi);
- if (bRet != FALSE)
- {
- if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE))
- {
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- }
- }
- _tprintf(_T("/r/n------------------------------------------/r/n"));
- }
- //end of AppCaller.cpp
- 获取命令行参数的各种变化
- 获取命令行参数的各种变化
- 获取命令行参数的各种变化
- 命令行参数的获取
- 获取进程的命令行参数
- golang获取命令行的参数
- 【Java】命令行参数的获取及判断
- 如何获取其它程序的命令行参数
- 如何获取其它程序的命令行参数
- .NET下获取命令行参数的方法
- 如何获取其它程序的命令行参数
- linux获取命令行参数的函数getopt
- Win32命令行参数的传入和获取
- 如何获取其它程序的命令行参数
- 使用ParamStr获取程序的命令行参数
- Delphi获取进程的命令行参数
- NodeJS获取命令行后面的参数
- 获取其他程序的命令行参数《转》
- 浅析数据结构之广义表
- 【NOIP2017提高组模拟12.10】幻魔皇
- 字符串分段(串)
- Mysql主从配置,实现读写分离
- 上传本地项目到git
- 获取命令行参数的各种变化
- win10 zlib编译
- 证明支配集问题是NP完全问题
- [51nod 1531]树上的博弈
- java 代理
- 形状属性
- 一个对象的内存图及运行流程和3个对象的内存图的运行流程
- Git实现从本地添加项目到远程仓库
- NOIP 提高组 初赛 四、阅读程序写结果 习题集(三)NOIP2002-NOIP2003