1.在新的VS版本中,会对老的一些函数做安全验证,导致编译报错,解决方案
在该文件的最上方 加上 #define _CRT_SECURE_NO_WARNINGS
2.对于某个应用,不需要弹出黑窗口,而是在后台静默运行
修改链接的部分,或者在代码中 添加 #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
3.对于互斥量的使用,一个程序只允许在当前的机器上打开一次,不能同时打开两个
HANDLE m_hMutex = CreateMutex(NULL, FALSE, L"krs_process_keep");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(m_hMutex);
m_hMutex = NULL;
return 0;
}
4.获取本地时间以宽字符的形式输出
std::wstring strLocalTime;
time_t nowtime;
struct tm* p;
time(&nowtime);
p = localtime(&nowtime);
TCHAR tmp[256];
wcsftime(tmp, sizeof(tmp), L"%Y-%m-%d %H:%M:%S", p);
strLocalTime = tmp;
这里的wcsftime 是专门用来格式化宽字符的函数
5.获取当前应用的所在目录和读取init文件(假设在该exe的目录下有一个user文件夹里面有一个setting.ini文件)
TCHAR szValue[MAX_PATH] = _T("");
TCHAR szModulePath[MAX_PATH] = { 0 };
ZeroMemory(szModulePath, MAX_PATH * sizeof(TCHAR));
::GetModuleFileName(NULL, szModulePath, MAX_PATH);
std::wstring strApp = szModulePath;
int nPos = strApp.find_last_of(_T('\\'));
strApp = strApp.substr(0, nPos + 1);
std::wstring strPath = strApp + _T("user\\settings.ini");
::GetPrivateProfileString(_T("Login"), _T("ServerAddr"), _T(""), szValue, MAX_PATH, strPath.c_str());
std::wstring strAddr = szValue;
::GetPrivateProfileString(_T("Login"), _T("Account"), _T(""), szValue, MAX_PATH, strPath.c_str());
std::wstring strAccount = szValue;
::GetPrivateProfileString(_T("Login"), _T("PassWord"), _T(""), szValue, MAX_PATH, strPath.c_str());
std::wstring strPassWord = szValue;
::GetPrivateProfileString(_T("Login"), _T("ServerPort"), _T(""), szValue, MAX_PATH, strPath.c_str());
std::wstring strPort = szValue;
文件内容:
[Login]
ServerAddr=192.168.0.1
ServerPort=80
Account=JamesWu9527
PassWord=123456
6.将应用程序提权(提升至管理员权限)这个是网上摘取的 链接在注释中
// https://blog.csdn.net/csdn_zhangchunfeng/article/details/83751544
bool KrsTools::EnableDebugPrivilege()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
return false;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
__try {
if (hToken) {
CloseHandle(hToken);
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {};
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
__try {
if (hToken) {
CloseHandle(hToken);
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {};
return false;
}
return true;
}
7.通过应用名获取进程ID
DWORD KrsTools::GetProcessIdFromName(const char* processName)
{
PROCESSENTRY32 pe;
DWORD id = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe))
return 0;
char pname[300];
do
{
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32Next(hSnapshot, &pe) == FALSE)
break;
sprintf(pname, "%ws", pe.szExeFile);
if (strcmp(pname, processName) == 0)
{
id = pe.th32ProcessID;
break;
}
} while (1);
CloseHandle(hSnapshot);
return id;
}
8.执行一个第三方程序(带参数)
void KrsTools::StartPrcess(std::wstring strProcessName,std::wstring strParam)
{
TCHAR tszProcess[64] = { 0 };
lstrcpy(tszProcess, strProcessName.c_str());
//启动程序
SHELLEXECUTEINFO shellInfo;
memset(&shellInfo, 0, sizeof(SHELLEXECUTEINFO));
shellInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shellInfo.fMask = NULL;
shellInfo.hwnd = NULL;
shellInfo.lpVerb = NULL;
shellInfo.lpFile = tszProcess; // 执行的程序名(绝对路径)
shellInfo.lpParameters = strParam.c_str(); // 执行程度的参数
shellInfo.lpDirectory = NULL;
shellInfo.nShow = NULL;
shellInfo.hInstApp = NULL;
ShellExecuteEx(&shellInfo);
}
9.HTTP访问
std::string KrsTools::HttpRequest(const TCHAR* lpHostName, const TCHAR* lpUrl,
const TCHAR* lpMethod, short sPort, char* lpPostData, int nPostDataLen)
{
HINTERNET hInternet = NULL, hConnect = NULL, hRequest = NULL;
TCHAR headerContentType[] = L"Content-Type:application/x-www-form-urlencoded";
TCHAR headAccept[] = L"Accept: application/json, text/plain, */*";
DWORD dwLastError = 0;
BOOL bRet;
std::string strResponse;
hInternet = (HINSTANCE)InternetOpen(L"User-Agent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hInternet)
{
std::cout << "InternetOpen user-agent failed" << std::endl;
//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("InternetOpen user-agent failed"));
goto end;
}
//hostname可以写www.baidu.com,不能写http://www.baidu.com,
hConnect = (HINSTANCE)InternetConnect(hInternet, lpHostName, sPort, NULL, L"HTTP/1.1", INTERNET_SERVICE_HTTP, 0, 0);
if (!hConnect)
{
std::cout << "InternetConnect failed" << std::endl;
//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("InternetConnect failed"));
goto end;
}
hRequest = (HINSTANCE)HttpOpenRequest(hConnect, lpMethod, lpUrl, L"HTTP/1.1", NULL, NULL, INTERNET_FLAG_RELOAD, 0);
if (!hRequest)
{
std::cout << "HttpOpenRequest failed" << std::endl;
//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("HttpOpenRequest failed"));
goto end;
}
///header可以加其他的///
//_tcslen(headerContentType)千万不要因为以前养成的好习惯而加上*sizeof(TCHAR),不然header中会有乱码,看起来是length表示的是utf-8的长度,不是占用的字节数
//nginx可能会报400
bRet = HttpAddRequestHeaders(hRequest, headerContentType, _tcslen(headerContentType), HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
if (!bRet)
{
std::cout << "HttpAddRequestHeaders failed" << std::endl;
//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("HttpAddRequestHeaders failed"));
goto end;
}
bRet = HttpAddRequestHeaders(hRequest, headAccept, _tcslen(headAccept), HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
if (!bRet)
{
std::cout << "HttpAddRequestHeaders2 failed" << std::endl;
//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("HttpAddRequestHeaders2 failed"));
goto end;
}
bRet = HttpSendRequest(hRequest, NULL, 0, lpPostData, nPostDataLen);
dwLastError = GetLastError();
while (TRUE)
{
char cReadBuffer[4096];
unsigned long lNumberOfBytesRead;
bRet = InternetReadFile(hRequest, cReadBuffer, sizeof(cReadBuffer) - 1, &lNumberOfBytesRead);
if (!bRet || !lNumberOfBytesRead)
{
break;
}
cReadBuffer[lNumberOfBytesRead] = 0;
strResponse = strResponse + cReadBuffer;
}
end:
if (hRequest)
InternetCloseHandle(hRequest);
if (hConnect)
InternetCloseHandle(hConnect);
if (hInternet)
InternetCloseHandle(hInternet);
return strResponse;
}
KrsTools::HttpRequest(strAddr.c_str(), strUrl.c_str(), L"get", _wtoi(strPort.c_str()));
参数:服务器地址,参数,访问方式,端口号