1. 程式人生 > >獲取命令列引數的各種變化

獲取命令列引數的各種變化

常,在VC++中獲取命令列引數的有如下幾種方式:

在控制檯程式中:

C++執行時庫通過入口函式main傳遞進來的引數int argc 和 char* argv[]。其中第二個引數將一個完整的命令列分割成指向各引數的字串指標陣列,陣列中的每一個元素是一個指向引數的字串指標。其中, argv[0] 指向應用程式名自身。

如果想獲得像視窗形式的完整命令列引數CmdLine的話,可以呼叫API GetCommandLine() 獲得。

在視窗程式中:

C++執行時庫通過入口函式WinMain傳遞進來的引數LPTSTR pszCmdLine。pszCmdLine是一個完整的命令列引數,包含應用程式名自身。

如果想獲得像控制檯形式的被分割的命令列引數指標陣列的話。可以使用如下程式碼獲得:

  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:

  1. //C++ code
  2. //Win32 project.
  3. //WinApp.cpp
  4. #include <Windows.h>
  5. #include <tchar.h>
  6. #include <strsafe.h>
  7. #include <stdarg.h>
  8. //使用XP風格的控制元件。
  9. #if defined _M_IX86
  10. #pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'/"")
  11. #endif
  12. //函式前導宣告。
  13. HRESULT FormatTextW(WCHAR **, size_t *, LPCWSTR, ...);  
  14. HRESULT AppendTextW(WCHAR **, size_t *, LPCWSTR);  
  15. HRESULT AppendMemHexW(WCHAR **, size_t *, LPBYTEint);  
  16. int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE/*hPrevInstance*/,  
  17.     LPTSTR lpCmdLine, int nCmdShow)  
  18. {  
  19.     int argc = 0;  
  20.     int chLen = 0;  
  21.     size_t bufLen = 0;  
  22.     HRESULT hr = S_OK;  
  23.     LPWSTR pszCmdLineW = NULL;  
  24.     LPWSTR *argv = NULL;  
  25.     WCHAR szText[1024] = { 0 };  
  26.     LPWSTR pCur = NULL;  
  27.     pszCmdLineW = GetCommandLineW();  
  28.     argv = CommandLineToArgvW(pszCmdLineW, &argc);  
  29.     //對命令列引數進行一些格式化,儲存到szText中,最後通過MessageBox進行顯示。
  30.     bufLen = _countof(szText);  
  31.     pCur = szText;  
  32.     if (SUCCEEDED(  
  33.         hr = FormatTextW(&pCur, &bufLen, L"GetCommandLineW=%s", pszCmdLineW)  
  34.         ) && SUCCEEDED(  
  35.         hr = AppendMemHexW(&pCur, &bufLen, (LPBYTE)pszCmdLineW,  
  36.         wcslen(pszCmdLineW)*sizeof(WCHAR))  
  37.         ) && SUCCEEDED(  
  38.         hr = AppendTextW(&pCur, &bufLen, L"/r/n")  
  39.         ) && SUCCEEDED(  
  40.         hr = AppendTextW(&pCur, &bufLen, L"CommandLineToArgvW:/r/n")  
  41.         ) && SUCCEEDED(  
  42.         hr = FormatTextW(&pCur, &bufLen, L"argc=%d/r/nargv:/r/n", argc)))  
  43.     {  
  44.         for (int i = 0; i < argc; i++)  
  45.         {  
  46.             hr = FormatTextW(&pCur, &bufLen, L"[#%u]%s", i, argv[i]);  
  47.             if (FAILED(hr)) break;  
  48.             hr = AppendMemHexW(&pCur, &bufLen, (LPBYTE)argv[i],  
  49.                 wcslen(argv[i])*sizeof(WCHAR));  
  50.             if (FAILED(hr)) break;  
  51.         }  
  52.     }  
  53.     if (argv != NULL) LocalFree(argv);  
  54.     if ((SUCCEEDED(hr)) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))  
  55.     {  
  56.         MessageBoxW(NULL, szText, L"Win App", MB_OK | MB_ICONINFORMATION);  
  57.     }  
  58.     return 0;  
  59. }  
  60. //格式化文字到緩衝區。
  61. HRESULT FormatTextW(WCHAR **ppBuf, size_t *pBufLen, LPCWSTR pszFormat, ...)  
  62. {  
  63.     va_list argList;  
  64.     va_start(argList, pszFormat);  
  65.     int chLen = 0;  
  66.     HRESULT hr = S_OK;  
  67.     hr = StringCchVPrintfExW(*ppBuf, *pBufLen, ppBuf, pBufLen,  
  68.         STRSAFE_IGNORE_NULLS, pszFormat, argList);  
  69.     va_end(argList);  
  70.     return hr;  
  71. }  
  72. //新增文字到緩衝區。
  73. HRESULT AppendTextW(WCHAR **ppBuf, size_t *pBufLen, LPCWSTR pszText)  
  74. {  
  75.     return StringCchCatExW(*ppBuf, *pBufLen, pszText, ppBuf, pBufLen,  
  76.         STRSAFE_IGNORE_NULLS);  
  77. }  
  78. //新增16進位制形式的記憶體位元組到緩衝區。
  79. HRESULT AppendMemHexW(WCHAR **ppBuf, size_t *pBufLen, LPBYTE pMem, int cbLen)  
  80. {  
  81.     HRESULT hr = S_OK;  
  82.     WCHAR sz[512] = { 0 };  
  83.     hr = StringCchCatEx(*ppBuf, *pBufLen, L"(", ppBuf, pBufLen,  
  84.         STRSAFE_IGNORE_NULLS);  
  85.     for (int i = 0; i < cbLen; i += 2)  
  86.     {  
  87.         hr = StringCchPrintfEx(*ppBuf, *pBufLen, ppBuf, pBufLen,  
  88.             STRSAFE_IGNORE_NULLS, L"%02x%02x", pMem[i], pMem[i+1]);  
  89.         if (FAILED(hr)) break;  
  90.         if (i != (cbLen - 2))  
  91.         {  
  92.             hr = StringCchCatEx(*ppBuf, *pBufLen, L" ", ppBuf, pBufLen,  
  93.                 STRSAFE_IGNORE_NULLS);  
  94.             if (FAILED(hr)) break;  
  95.         }  
  96.     }  
  97. 相關推薦

    獲取命令引數各種變化

    常,在VC++中獲取命令列引數的有如下幾種方式: 在控制檯程式中: C++執行時庫通過入口函式main傳遞進來的引數int argc 和 char* argv[]。其中第二個引數將一個完整的命令列分割成指向各引數的字串指標陣列,陣列中的每一個元素是一個

    electron 獲取命令引數

    一 實現 最近要做一個小工具,基於electron的獨立程序,從平臺中雙擊圖示,能夠啟動electron,並且要攜帶一些必要的命令列引數。以為是個很簡單的實現,但發現electron的文件中並沒有說明。最後在atom的討論網站中找到了一個答案,如下: 1 假如你傳的引數為arg1 arg

    Go基礎程式設計:獲取命令引數

    package main import ( "fmt" "os" //os.Args所需的包 ) func main() { args := os.Args //獲取使用者輸入的所有引數 //如果使用者沒有輸入

    Python獲取命令引數

    sys.argv[] 包含命令列引數的字串列表,通過下標獲取引數。 例如: #!/usr/bin/python # Filename: using_sys.py import sys print 'The command line arguments

    python獲取命令引數的幾種方法總結

    第一種是利用sys.argv模組 import sys print sys.argv 輸出整個命令列,以list的格式,所以有時候可以通過判斷這個list的長度來判斷是否有引數值輸入。 print sys.argv[0] print sys.argv[1] prin

    python 獲取命令引數

    最近因工作需要使用Python寫個指令碼,用到了獲取命令列引數,這裡順便總結下做個筆記,下次用到過來瞅瞅就方便的多了 import sys import getopt def usage(): print ("sys.argv[0]: '-a aa -b bb -

    Linux 使用getopts命令獲取命令引數

    Linux getopts命令用於獲取命令列中的引數 呼叫格式: getopts option_string variable   引數說明: option_string 選項名稱 variable 選項的值   選項之間使用冒號:分隔,也可以直

    .NET Core採用的全新配置系統[5]: 聊聊預設支援的各種配置源[記憶體變數,環境變數和命令引數]

    較之傳統通過App.config和Web.config這兩個XML檔案承載的配置系統,.NET Core採用的這個全新的配置模型的最大一個優勢就是針對多種不同配置源的支援。我們可以將記憶體變數、命令列引數、環境變數和物理檔案作為原始配置資料的來源,如果採用物理檔案作為配置源,我們可以選擇不同的格式(比如XML

    Win32命令引數的傳入和獲取

    Win32控制檯,如何傳入和獲取命令列引數的有關問題, 有幾種解決辦法, 總結出來,朋友們一起分享 // tt.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> #include

    命令引數獲取

    時不時我們會遇到對命令含引數的處理,如果引數個數較多,按照順序處理有可能會出現錯誤或者一些可選引數將不能實現,接下來介紹幾個處理命令列引數的函式 getopt #include <

    命令:獲取使用者命令引數Option

    執行引數: 程式碼 package com.donews.data.hbaseuser import java.time.LocalDate import com.donews.dat

    如何獲取Windows命令引數資訊(和Linux中的ps -ef的輸出相似)

    #列出所有程序資訊 CMD>wmic process #列出所有java程序 CMD>wmic process where caption="java.exe" 注:Windows最令網管詬病的地方就是命令列沒有Unix和Linux強大。但這種情況正在不斷改觀

    ssdeep命令引數說明

    ssdeep 下載地址: http://ssdeep.sourceforge.net/ ssdeep 中文介紹: http://blog.claudxiao.net/2012/02/fuzzy_hashing/#comment-489

    x265 命令引數大全

    除非一個引數被標記為 CLI ONLY,否則該引數也被x265_param_parse() 支援。CLI使用getopt 函式來解釋命令列引數,長短版本的引數都可以使用,長引數在不引起歧義的情況下可以截斷成短引數。API使用者必須把完整的引數名傳遞給 x265_param_parse()。 Pres

    MFC解析啟動命令引數——CCommandLineInfo類

    MFC中CCommandLineInfo類被用於分析啟動應用時的命令列引數。 MFC應用一般都會在它的應用物件中使用函式InitInstance()建立這個類的一個本地例項。然後把該物件傳給CWinApp::ParseCommandLine(),ParseCommandLine()又重複呼叫

    argparse配合pycharm命令引數

    1、未新增命令列引數的時候 import argparse parser = argparse.ArgumentParser() parser.add_argument("square", type=int, help="display a square of a given number")

    impala-shell命令引數

    轉發 https://my.oschina.net/weiqingbin/blog/190929 你可以在啟動 impala-shell 時設定以下選項,用於修改命令執行環境。   Note: 這些選項與 impalad 守護程序的配置選

    CreateProcess 建立帶命令引數的程序時,報錯或者提示記憶體位置無效的可能的一個原因

    可能的一個原因:命令列引數使用了常量。 例如: CreateProcess(NULL, "notepad",NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi); 解釋: pszApplicationName和ps

    nginx使用手冊--nginx的命令引數

    nginx的命令列引數 -? 或者 -h 列印命令列引數幫助資訊 -c file 為 Nginx 指定一個配置檔案,來代替預設的。 -t 不執行,而僅僅測試配置檔案。nginx 將檢查配置檔案的語法的正確性,並嘗試開啟配置檔案中所引用到的檔案。 -v 顯示 nginx 的版本。 -V

    【C程式編譯連結】gcc使用命令介紹 gcc的使用簡介與命令引數說明

    1.gcc或者g++安裝rpm -qa|grep gcc ==>檢查gcc是否安裝gcc -v ==>檢查gcc版本 編譯器會在可執行檔案中植入一些資訊,可執行檔案會變大。一般開發時候使用 -g ,編譯一個 “release 版本” 時不使用 -g 編譯。gcc如果是最新的則不重