一種解決啟動程序傳遞引數過長的方法

2021-06-18 23:03:38 字數 2773 閱讀 8979

hinstance shellexecute(

_in_opt_ hwnd hwnd,

_in_opt_ lpctstr lpoperation,

_in_ lpctstr lpfile,

_in_opt_ lpctstr lpparameters,

_in_opt_ lpctstr lpdirectory,

_in_ int nshowcmd

);

其中不成功的場景是:我們給lpparameters傳遞了大概32k位元組長度的引數。

我當時就覺得這個是因為shellexcute中引數長度限制問題。我決定將這個邏輯使用createprocess去實現,這樣我將會有更多的控制權力。但是最後我們發現問題還是依舊的,因為我們檢視msdn關於createprocess的lpcommandline說明:

lpcommandline [in, out, optional]

the command line to be executed. the maximum length of this string is 32,768 characters, including the unicode terminating null character.

它最長只可以穿32768個字元(而我之後測試結果卻是32766)。看來簡單的使用createprocess還是不能解決我們的問題。

為了解決這個問題,我們首先分析問題出現的場景:

a程序去啟動b程序

a程序啟動b程序時要傳遞乙個很長的資料

a程序不關心b程序執行結果和生命週期

b程序不關心a程序的生命週期

遇到這類問題,首先肯定先想到,使用管道(pipe)或者socket這類程序間通訊手段。這個方法可以解決上述特點中的1、2兩個問題。但是管道和socket給人最直觀的映像就是:雙方互動式通訊。即a要關心b的存在與否,b也要關心a的存在與否。任何一方斷了,都會影響另一方的流程。這個和我們上述特點中的3、4是相背的。那麼怎麼解決呢?我想到了另乙個程序間通訊的方法——記憶體對映檔案。

記憶體對映檔案分為兩種,一種是「命名」檔案,一種是「匿名」記憶體對映檔案。「命名」檔案一般用於安全性要求不高的程序間通訊,而「匿名」記憶體對映檔案一般是用於安全性較高的程序間通訊。我們肯定優先考慮安全性更高的「匿名」記憶體對映檔案。我舉乙個之前我寫得工程的例子解釋如何使用「匿名」記憶體對映檔案進行程序間通訊的:

a和b程序建立管道連線

a建立乙個「匿名」記憶體對映檔案

a開啟b程序控制代碼

a將「匿名」記憶體對映檔案handle duplicate給b程序,生成b程序可以使用的handleb

a將handleb通過管道傳遞給程序b

程序b使用handleb訪問資料

這個流程給出了乙個使用匿名管道進行程序間通訊的乙個必要的條件:b程序的已經存在,並且可以通知b程序去使用duplicate後的handleb。

在我們的場景中,就是不希望使用除了檔案對映之外的通訊方式。而且,我們要在b程序建立時,就將檔案對映傳給b程序,所以無法使用「匿名」記憶體對映檔案。

目前只剩下「命名」記憶體對映檔案一條路可以走了。雖然這種方式存在種種不安全性,但是它是目前場景下唯一可以選擇的方向。

為了不存在「名稱」的衝突問題。我選擇了隨機生成「名稱」的方案

; wsprintf( wchname, l"%d", rand());}

雖然每次都是隨機的,但是我還是不放心這個「隨機」碰撞的概率。於是我在建立記憶體對映檔案時判斷了下當前建立的「名字」是否在系統中已經存在。如果存在,我會重新隨機生成名字並建立該名字的記憶體對映檔案。

if ( error_already_exists == ::getlasterror() )

else

}else

}while (true);

return true;}

待記憶體對映檔案建立成功後,我們往該「檔案」中寫入資料,其資料格式是:前sizeof(dword)儲存的是要傳遞給子程序的資料長度,其後跟著資料內容。

struct stdata ;
具體的資料填充**是

bool ctransmitparam::packdata( 

lpvoid lpmem,

dword dwnewbuffersize,

lpcbyte lpbuffer,

dword dwbuffersize )

if ( 0 == m_dwrecvbufferlength )

m_lprecvbuffer = new byte[m_dwrecvbufferlength];

memset( m_lprecvbuffer, 0, sizeof(m_lprecvbuffer));

e = memcpy_s( m_lprecvbuffer, m_dwrecvbufferlength, (lpbyte)lpmem + sizeof(dword), m_dwrecvbufferlength );

if ( 0 != e )

bsuc = true;

} while (0);

return bsuc;

} bool bsuc = false;

do if ( null == lpmem )

if ( false == unpackdata(lpmem) )

unmapviewoffile(lpmem);

bsuc = true;

} while (0);

return bsuc;

}

啟動logstash失敗的一種解決方法

修改裡面的配置,把原來的1g改為2g試試,我就是這個問題,然後仍出現 findstr 不是內部或外部命令不用管,照常輸入啟動命令還是會執行的 xms represents the initial size of total heap space xmx represents the maximum ...

優化JS載入時間過長的一種思路

去年公司在漳州的乙個專案中,現場工程人員反映地圖部分出圖有點緩慢,大約需要20多秒。和另外乙個同事一起花了一兩天進行了 優化 壓縮 中介軟體優化以及服務部署優化後使地圖出圖縮短到了9秒上下。這裡對上次的經驗做乙個總結,提供一種優化js檔案載入時間過長的思路。這裡的中介軟體使用的是tomcat6.0。...

C 呼叫python指令碼並傳遞引數的一種方法

1 c 裡面怎麼呼叫python指令碼?2 python指令碼裡面怎麼獲取引數?先回答第乙個 c 裡面system.diagnostics.process.start 這裡面可以呼叫系統命令和程式 我們這裡只需要這樣寫就可以呼叫c say.py指令碼了,如下 system.diagnostics.p...