1.VS2015编码为unicode,fopen打开文件也应该是Unicode文件,才能从文件中查找特定的字符串
2.系统命令systeminfo保存为Unicode文件
systeminfo.bat
powershell -c "systeminfo | Out-File -Encoding unicode systeminfo.txt"
或者
powershell -c "Set-Content 'systeminfo.txt' -Value (systeminfo) -Encoding Unicode"
3.代码实现查找补丁KB4013429
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
#include<shlwapi.h>
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPTSTR szCmdline=_tcsdup(TEXT("systeminfo.bat"));
// Start the child process.
if (!CreateProcess(NULL, // No module name (use command line)
szCmdline, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi) // Pointer to PROCESS_INFORMATION structure
)
{
//printf("CreateProcess failed (%d).\n", GetLastError());
//return 0;
CString str; // 这是MFC中的字符串变量
str.Format(_T(" CreateProcess failed (%d)"), GetLastError()); // 调用Format方法将变量转换成字符串,第一个参数就是变量类型
//MessageBox(str, _T(""), MB_ICONINFORMATION);
AfxMessageBox(str, MB_ICONINFORMATION);
exit(0);
}
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
FILE * pFile;
long lSize;
LPTSTR buffer;
size_t result;
// 若要一个byte不漏地读入整个文件,只能采用二进制方式打开
pFile = fopen("systeminfo.txt", "rb");
if (pFile == NULL)
{
fputs("File error", stderr);
exit(1);
}
//获取文件大小
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);
//分配内存存储整个文件
buffer = (LPTSTR)malloc(sizeof(LPTSTR)*lSize);
if (buffer == NULL)
{
fputs("Memory error", stderr);
exit(2);
}
//将文件拷贝到buffer中
//fwrite(buffer, size, count, fp);
//fwrite(buffer, 1, lSize, pFile);
result = fread(buffer, 1, lSize, pFile);
if (result != lSize)
{
fputs("Reading error", stderr);
exit(3);
}
// 现在整个文件已经在buffer中,可由标准输出打印内容
printf("%s\n\n\n\n", buffer);
//LPTSTR patch = _T("KB4013429");
LPTSTR patch = _T("KB4013429");
if (_tcsstr(buffer, patch))
{
printf("pass\n");
}
else
printf("fail\n");
printf("finish\n");
// 结束演示,关闭文件并释放内存
fclose(pFile);
free(buffer);
//*/
return 0;
}
4.结果
MFC 采用管道方法
void CRuncmdDlg::OnOK()
{
// TODO: Add extra validation here
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL; //使用系统默认的安全描述符
sa.bInheritHandle = TRUE; //创建的进程继承句柄
if (!CreatePipe(&hRead,&hWrite,&sa,0)) //创建匿名管道
{
MessageBox(_T("CreatePipe Failed!"),_T("Tip"),MB_OK | MB_ICONWARNING);
return;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite; //新创建进程的标准输出连在写管道一端
si.wShowWindow = SW_HIDE; //隐藏窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
TCHAR cmdline[256] = {_T("systeminfo.exe")};
//CString tmp,stredit2;
// GetDlgItemText(IDC_EDIT2,stredit2); //获取编辑框中输入的命令行
// tmp.Format(_T("cmd /C %s"),stredit2);
// _stprintf(cmdline,_T("%s"),tmp);
#ifdef _UNICODE
//MessageBox(_T("UNICODE!"), _T("提示"), MB_OK | MB_ICONWARNING);
#else
//MessageBox(_T("ANSI!"), _T("提示"), MB_OK | MB_ICONWARNING);
#endif
if (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) //创建子进程
{
MessageBox(_T("CreateProcess Failed!"),_T("Tip"),MB_OK | MB_ICONWARNING);
return;
}
CloseHandle(hWrite); //关闭管道句柄
char buffer[4096] = {0};
CString strOutput;
CString PatchKB = {_T("KB3186568")};
DWORD bytesRead;
while (true)
{
if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL) //读取管道
break;
strOutput += buffer;
SetDlgItemText(IDC_EDIT1,strOutput); //显示输出信息到编辑框,并刷新窗口
//AfxMessageBox(strOutput);
//UpdateWindow();
//Sleep(100);
}
if (_tcsstr(strOutput, PatchKB))
{
AfxMessageBox(_T("Pass"));
}
else
AfxMessageBox(_T("Fail"));
CloseHandle(hRead);
// CDialog::OnOK();
}