📄 execute.cpp
字号:
// execute.cpp
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "msc.h"
#include "execute.h"
#define CREATE_PROCESS_FLAGS CREATE_DEFAULT_ERROR_MODE
//////////////////////////////
// ANSI斉 //
//////////////////////////////
static int ExecuteInternalA ( char *szCmdLine, int nCmdShow, unsigned long dwTimeOut, int *pExitCode ) ;
// 僐儅儞僪傪幚峴偟丄巜掕偝傟偨帪娫傑偱懸偮乮ANSI斉乯
// dwTimeOut 偵偼儈儕昩丄傑偨偼 INFINITE 傪巜掕偡傞
// 僐儅儞僪傪幚峴偱偒側偐偭偨偲偒偼 0 埲奜偺惓悢傪曉偡
// 帪娫傪挻夁偟偨偲偒偼晧悢傪曉偡
// 廔椆帪偵 pExitCode 偵僄儔乕僐乕僪傪奿擺偡傞乮昁梫偱側偗傟偽 NULL 偱傕壜乯
// szCmdLine 偺僐儅儞僪柤偼丄憡懳僷僗柤丄僷僗柤柍偟偱巜掕偟偰傕壜
// nCmdShow 偼丄恊僾儘僙僗偐傜宲彸偡傞偲偒偼 SW_SHOWDEFAULT 傪丄巜掕偟側偄側傜 -1 傪巜掕偡傞
int ExecuteA ( const char *szCmdLine, int nCmdShow, unsigned long dwTimeOut, int *pExitCode ) {
if ( ! szCmdLine ) szCmdLine = "" ;
char *szCmdLineBuffer = strdup_expand ( szCmdLine, (size_t) -1, 8 ) ;
if ( ! szCmdLineBuffer ) return 1 ;
int nResult = ExecuteInternalA ( szCmdLineBuffer, nCmdShow, dwTimeOut, pExitCode ) ;
free ( szCmdLineBuffer ) ;
return nResult ;
}
// ExecuteA 偺壓惪偗娭悢
// 堷偒悢 szCmdLine 偼旕 const 偱丄僶僢僼傽偺挿偝偼悢暥帤暘偺梋桾傪
// 乮 CreateProcess 偺戞俀堷偒悢偺惂尷偺偨傔乯
// 栠傝抣偼 ExecuteA 偲摨偠
static int ExecuteInternalA ( char *szCmdLine, int nCmdShow, unsigned long dwTimeOut, int *pExitCode ) {
int nResult = 1 ;
unsigned long nExitCode = 0 ;
// 婲摦娐嫬傪愝掕
PROCESS_INFORMATION ProcessInfo = { 0 } ;
STARTUPINFOA StartupInfo = { 0 } ;
StartupInfo.cb = sizeof(STARTUPINFOA) ;
if ( nCmdShow == SW_SHOWDEFAULT ) {
STARTUPINFOA ParentInfo = { 0 } ;
ParentInfo.cb = sizeof(STARTUPINFOA) ;
GetStartupInfoA ( & ParentInfo ) ;
if ( ParentInfo.dwFlags & STARTF_USESHOWWINDOW ) nCmdShow = ParentInfo.wShowWindow ;
else nCmdShow = -1 ;
}
if ( nCmdShow >= 0 && nCmdShow <= SW_MAX ) {
StartupInfo.dwFlags |= STARTF_USESHOWWINDOW ;
StartupInfo.wShowWindow = nCmdShow ;
}
// 幚峴
if ( CreateProcessA ( NULL, szCmdLine, NULL, NULL, FALSE, CREATE_PROCESS_FLAGS, NULL, NULL, & StartupInfo, & ProcessInfo ) ) {
CloseHandle ( ProcessInfo.hThread ) ;
// 懸婡
if ( dwTimeOut && WaitForSingleObject ( ProcessInfo.hProcess, dwTimeOut ) == WAIT_TIMEOUT ) nResult = -1 ;
else nResult = 0 ;
// 僄儔乕僐乕僪傪庢摼
if ( pExitCode ) {
if ( dwTimeOut && ! nResult ) GetExitCodeProcess ( ProcessInfo.hProcess, & nExitCode ) ;
*pExitCode = nExitCode ;
}
CloseHandle ( ProcessInfo.hProcess ) ;
}
return nResult ;
}
// system() 偺戙懼娭悢乮ANSI斉乯
// CRT偺娐嫬曄悢傪棙梡偟側偄
int ExecuteViaComspecA ( const char *szCmdLine ) {
char szComspec [ MAX_PATH ] ;
static const char szComspecOption [] = " /c " ; // 慜屻偵僗儁乕僗傪
int nExitCode ;
int nResult ;
// 僐儅儞僪僀儞僞僾儕僞傪庢摼
nResult = GetEnvironmentVariableA ( "COMSPEC", szComspec, MAX_PATH ) ;
if ( nResult <= 0 || nResult >= MAX_PATH ) {
char *szTmp ;
const char *szPredefinedComspec = IsNT () ? "CMD.EXE" : "COMMAND.COM" ;
nResult = SearchPathA ( NULL, szPredefinedComspec, NULL, MAX_PATH, szComspec, & szTmp ) ;
if ( nResult <= 0 || nResult >= MAX_PATH ) strcpy ( szComspec, szPredefinedComspec ) ;
}
if ( ! szCmdLine ) {
unsigned long dwAttributes = GetFileAttributesA ( szComspec ) ;
if ( dwAttributes != (unsigned long) -1 && ! ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) return 1 ;
errno = ENOENT ;
return 0 ;
}
char *szCmdLineBuffer = (char*) malloc ( ( strlen ( szComspec ) + strlen ( szComspecOption ) + strlen ( szCmdLine ) + 8 ) * sizeof(char) ) ;
if ( ! szCmdLineBuffer ) {
errno = E2BIG ;
return -1 ;
}
// 僐儅儞僪儔僀儞傪嶌惉
if ( strchr ( szComspec, 0x20 ) ) {
strcpy ( szCmdLineBuffer, "\"" ) ;
strcat ( szCmdLineBuffer, szComspec ) ;
strcat ( szCmdLineBuffer, "\"" ) ;
}
else {
strcpy ( szCmdLineBuffer, szComspec ) ;
}
strcat ( szCmdLineBuffer, szComspecOption ) ;
// 僐儅儞僪柤偵堷梡晞偑偁傞偲偒偼丄"CMD.EXE /C" 偺偁偲偺暥帤楍慡懱傪偝傜偵堷梡晞偱埻傓
if ( IsNT () && *szCmdLine == '\"' ) {
strcat ( szCmdLineBuffer, "\"" ) ;
strcat ( szCmdLineBuffer, szCmdLine ) ;
strcat ( szCmdLineBuffer, "\"" ) ;
}
else {
strcat ( szCmdLineBuffer, szCmdLine ) ;
}
// 幚峴
nResult = ExecuteInternalA ( szCmdLineBuffer, -1, INFINITE, & nExitCode ) ;
free ( szCmdLineBuffer ) ;
if ( nResult > 0 ) {
errno = ENOENT ;
return -1 ;
}
return nExitCode ;
}
// 僐儅儞僪儔僀儞偱惓偟偔夝庍偱偒傞傛偆堷偒悢傪廋惓偡傞
// buffer 偑 NULL 側傜偽彂偒崬傑偢偵挿偝傪寁嶼偡傞
// 挿偝傪傪曉偡乮廔抂僰儖暥帤傪娷傓乯
size_t EncodeArgumentToCrtStyleA ( const char *szSrc, char *szDst ) {
int IsAddQuote = strchr ( szSrc, 0x20 ) || strchr ( szSrc, '\t' ) || strchr ( szSrc, '&' ) ;
char *szStart = szDst ;
if ( IsAddQuote ) {
if ( szStart ) *szDst ++ = '\"' ;
else szDst ++ ;
}
while ( *szSrc ) {
if ( *szSrc == '\\' ) {
int IsBackslashQuote = 0 ;
for ( const char *p = szSrc ; p ; p ++ ) {
if ( *p == '\"' || ! *p && IsAddQuote ) { IsBackslashQuote = 1 ; break ; }
if ( *p != '\\' ) break ;
}
if ( IsBackslashQuote ) {
while ( *szSrc == '\\' ) {
if ( szStart ) *szDst ++ = *szSrc ++ ;
else szDst ++, szSrc ++ ;
if ( szStart ) *szDst ++ = '\\' ;
else szDst ++ ;
}
continue ;
}
}
if ( *szSrc == '\"' ) {
if ( szStart ) *szDst ++ = '\\' ;
else szDst ++ ;
}
if ( szStart ) *szDst ++ = *szSrc ++ ;
else szDst ++, szSrc ++ ;
}
if ( IsAddQuote ) {
if ( szStart ) *szDst ++ = '\"' ;
else szDst ++ ;
}
if ( szStart ) *szDst ++ = 0 ;
else szDst ++ ;
return szDst - szStart ;
}
//////////////////////////////
// UNICODE斉 //
//////////////////////////////
static int ExecuteInternalW ( wchar_t *szCmdLine, int nCmdShow, unsigned long dwTimeOut, int *pExitCode ) ;
// 僐儅儞僪傪幚峴偟丄巜掕偝傟偨帪娫傑偱懸偮乮UNICODE斉乯
// dwTimeOut 偵偼儈儕昩丄傑偨偼 INFINITE 傪巜掕偡傞
// 僐儅儞僪傪幚峴偱偒側偐偭偨偲偒偼 0 埲奜偺惓悢傪曉偡
// 帪娫傪挻夁偟偨偲偒偼晧悢傪曉偡
// 廔椆帪偵 pExitCode 偵僄儔乕僐乕僪傪奿擺偡傞乮昁梫偱側偗傟偽 NULL 偱傕壜乯
// szCmdLine 偺僐儅儞僪柤偼丄憡懳僷僗柤丄僷僗柤柍偟偱巜掕偟偰傕壜
// nCmdShow 偼丄恊僾儘僙僗偐傜宲彸偡傞偲偒偼 SW_SHOWDEFAULT 傪丄巜掕偟側偄側傜 -1 傪巜掕偡傞
int ExecuteW ( const wchar_t *szCmdLine, int nCmdShow, unsigned long dwTimeOut, int *pExitCode ) {
if ( ! szCmdLine ) szCmdLine = L"" ;
wchar_t *szCmdLineBuffer = wcsdup_expand ( szCmdLine, (size_t) -1, 8 ) ;
int nResult = ExecuteInternalW ( szCmdLineBuffer, nCmdShow, dwTimeOut, pExitCode ) ;
free ( szCmdLineBuffer ) ;
return nResult ;
}
// ExecuteW 偺壓惪偗娭悢
// 堷偒悢 szCmdLine 偼旕 const 偱丄僶僢僼傽偺挿偝偼悢暥帤暘偺梋桾傪
// 乮 CreateProcess 偺戞俀堷偒悢偺惂尷偺偨傔乯
// 栠傝抣偼 ExecuteW 偲摨偠
static int ExecuteInternalW ( wchar_t *szCmdLine, int nCmdShow, unsigned long dwTimeOut, int *pExitCode ) {
int nResult = 1 ;
unsigned long nExitCode = 0 ;
// 婲摦娐嫬傪愝掕
PROCESS_INFORMATION ProcessInfo = { 0 } ;
STARTUPINFOW StartupInfo = { 0 } ;
StartupInfo.cb = sizeof(STARTUPINFOW) ;
if ( nCmdShow == SW_SHOWDEFAULT ) {
STARTUPINFOW ParentInfo = { 0 } ;
ParentInfo.cb = sizeof(STARTUPINFOW) ;
GetStartupInfoW ( & ParentInfo ) ;
if ( ParentInfo.dwFlags & STARTF_USESHOWWINDOW ) nCmdShow = ParentInfo.wShowWindow ;
else nCmdShow = -1 ;
}
if ( nCmdShow >= 0 && nCmdShow <= SW_MAX ) {
StartupInfo.dwFlags |= STARTF_USESHOWWINDOW ;
StartupInfo.wShowWindow = nCmdShow ;
}
// 幚峴
if ( CreateProcessW ( NULL, szCmdLine, NULL, NULL, FALSE, CREATE_PROCESS_FLAGS, NULL, NULL, & StartupInfo, & ProcessInfo ) ) {
CloseHandle ( ProcessInfo.hThread ) ;
// 懸婡
if ( dwTimeOut && WaitForSingleObject ( ProcessInfo.hProcess, dwTimeOut ) == WAIT_TIMEOUT ) nResult = -1 ;
else nResult = 0 ;
// 僄儔乕僐乕僪傪庢摼
if ( pExitCode ) {
if ( dwTimeOut && ! nResult ) GetExitCodeProcess ( ProcessInfo.hProcess, & nExitCode ) ;
*pExitCode = nExitCode ;
}
CloseHandle ( ProcessInfo.hProcess ) ;
}
return nResult ;
}
// system() 偺戙懼娭悢乮UNICODE斉乯
// CRT偺娐嫬曄悢傪棙梡偟側偄
int ExecuteViaComspecW ( const wchar_t *szCmdLine ) {
wchar_t szComspec [ MAX_PATH ] ;
static const wchar_t szComspecOption [] = L" /c " ; // 慜屻偵僗儁乕僗傪
int nExitCode ;
int nResult ;
// 僐儅儞僪僀儞僞僾儕僞傪庢摼
nResult = GetEnvironmentVariableW ( L"COMSPEC", szComspec, MAX_PATH ) ;
if ( nResult <= 0 || nResult >= MAX_PATH ) {
wchar_t *szTmp ;
const wchar_t *szPredefinedComspec = IsNT () ? L"CMD.EXE" : L"COMMAND.COM" ;
nResult = SearchPathW ( NULL, szPredefinedComspec, NULL, MAX_PATH, szComspec, & szTmp ) ;
if ( nResult <= 0 || nResult >= MAX_PATH ) wcscpy ( szComspec, szPredefinedComspec ) ;
}
if ( ! szCmdLine ) {
unsigned long dwAttributes = GetFileAttributesW ( szComspec ) ;
if ( dwAttributes != (unsigned long) -1 && ! ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) return 1 ;
errno = ENOENT ;
return 0 ;
}
wchar_t *szCmdLineBuffer = (wchar_t*) malloc ( ( wcslen ( szComspec ) + wcslen ( szComspecOption ) + wcslen ( szCmdLine ) + 8 ) * sizeof(wchar_t) ) ;
if ( ! szCmdLineBuffer ) {
errno = E2BIG ;
return -1 ;
}
// 僐儅儞僪儔僀儞傪嶌惉
if ( wcschr ( szComspec, 0x20 ) ) {
wcscpy ( szCmdLineBuffer, L"\"" ) ;
wcscat ( szCmdLineBuffer, szComspec ) ;
wcscat ( szCmdLineBuffer, L"\"" ) ;
}
else {
wcscpy ( szCmdLineBuffer, szComspec ) ;
}
wcscat ( szCmdLineBuffer, szComspecOption ) ;
// 僐儅儞僪柤偵堷梡晞偑偁傞偲偒偼丄"CMD.EXE /C" 偺偁偲偺暥帤楍慡懱傪偝傜偵堷梡晞偱埻傓
if ( IsNT () && *szCmdLine == '\"' ) {
wcscat ( szCmdLineBuffer, L"\"" ) ;
wcscat ( szCmdLineBuffer, szCmdLine ) ;
wcscat ( szCmdLineBuffer, L"\"" ) ;
}
else {
wcscat ( szCmdLineBuffer, szCmdLine ) ;
}
// 幚峴
nResult = ExecuteInternalW ( szCmdLineBuffer, -1, INFINITE, & nExitCode ) ;
free ( szCmdLineBuffer ) ;
if ( nResult > 0 ) {
errno = ENOENT ;
return -1 ;
}
return nExitCode ;
}
// 僐儅儞僪儔僀儞偱惓偟偔夝庍偱偒傞傛偆堷偒悢傪廋惓偡傞
// buffer 偑 NULL 側傜偽彂偒崬傑偢偵挿偝傪寁嶼偡傞
// 挿偝傪傪曉偡乮廔抂僰儖暥帤傪娷傓乯
size_t EncodeArgumentToCrtStyleW ( const wchar_t *szSrc, wchar_t *szDst ) {
int IsAddQuote = wcschr ( szSrc, 0x20 ) || wcschr ( szSrc, '\t' ) || wcschr ( szSrc, '&' ) ;
wchar_t *szStart = szDst ;
if ( IsAddQuote ) {
if ( szStart ) *szDst ++ = '\"' ;
else szDst ++ ;
}
while ( *szSrc ) {
if ( *szSrc == '\\' ) {
int IsBackslashQuote = 0 ;
for ( const wchar_t *p = szSrc ; p ; p ++ ) {
if ( *p == '\"' || ! *p && IsAddQuote ) { IsBackslashQuote = 1 ; break ; }
if ( *p != '\\' ) break ;
}
if ( IsBackslashQuote ) {
while ( *szSrc == '\\' ) {
if ( szStart ) *szDst ++ = *szSrc ++ ;
else szDst ++, szSrc ++ ;
if ( szStart ) *szDst ++ = '\\' ;
else szDst ++ ;
}
continue ;
}
}
if ( *szSrc == '\"' ) {
if ( szStart ) *szDst ++ = '\\' ;
else szDst ++ ;
}
if ( szStart ) *szDst ++ = *szSrc ++ ;
else szDst ++, szSrc ++ ;
}
if ( IsAddQuote ) {
if ( szStart ) *szDst ++ = '\"' ;
else szDst ++ ;
}
if ( szStart ) *szDst ++ = 0 ;
else szDst ++ ;
return szDst - szStart ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -