Windows常用代码
常用工具代码
判断进程位数
// 判断进程是否为 64 位进程
BOOL Is64BitProcess(DWORD processId, LPBOOL is64Bit)
{
BOOL result = FALSE;
if (Is64BitOperatingSystem())
{
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
if (process)
{
BOOL wow64;
if (IsWow64Process(process, &wow64))
{
*is64Bit = wow64 ? FALSE : TRUE;
result = TRUE;
}
CloseHandle(process);
}
}
else
{
*is64Bit = FALSE;
result = TRUE;
}
return result;
}
判断操作系统位数
// 判断操作系统是否为 64 位操作系统
BOOL Is64BitOperatingSystem()
{
BOOL wow64 = FALSE;
return BITNESS(64) || IsWow64Process(GetCurrentProcess(), &wow64) && wow64;
}
获取系统当前时间
#include<time.h>
time_t timeSec=time (NULL); //获取1970.1.1至当前秒数time_t
struct tm * timeinfo= localtime ( &timeSec ); //创建TimeDate,并转化为当地时间,
//struct tm * timeinfo = gmtime ( &timeSec ); //创建TimeDate,并转化为GM时间,
printf ( "The current date/time is: %s\n", asctime (timeinfo) );
//获取年 月 日 时 分 秒 对应的int值:
printf("%d-%d-%d %d:%d:%d\n",timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
/*写入日志*/
time_t timep;
struct tm* p;
time_t timeSec = time(NULL);
struct tm* timeinfo = localtime(&timeSec);
fprintf(Logfp, "%d-%d-%d %d:%d:%d\n", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
fprintf(Logfp, "File location:%s\nLOG:%s\n",BuildPath, CurPath);
fclose(Logfp);
IP校验
字符串验证
#include <iostream>
#include <string>
using namespace std;
/*
IPv6的错误形式可能有如下:
1.多了0
2.出现::
3.字符不在0-9 a-f A-F之间
IPv4错误形式可能有如下:
1.多了首位'0'
2.超过0-255范围
3.首位是"."或出现的".."
4.不能为 '.'和’0-9‘ 之外的数字
5.不为4段
*/
class SolutionIP{
public:
// 判断类型 false:ipv4 true:ipv6
bool type(string &s){
for(auto ch:s){
if(ch=='.') return false;
if(ch==':') return true;
}
}
bool checkV6(string &s){
int ch_cnt = 0;
for(int i=0; i<s.size(); ++i){
if(s[i]==':'){
if(ch_cnt>4 || ch_cnt==0) return false;
ch_cnt = 0;
} else if(!( s[i]<='9' && s[i]>='0'
||s[i]<='F' && s[i]>='A'
||s[i]<='f' && s[i]>='a'
)){
return false;
} else {
ch_cnt++;
}
}
return true;
}
bool checkV4(string &s){
int k=0; //记录每个segment起始位置
int pCnt=0; //记录'.'的个数
s.push_back('.'); //方便atoi使用
for(int i=0; i<s.size(); ++i){
if(s[i] == '.'){
s[i] = '\0'; //方便atoi使用
if( s[k]=='\0' //连续..或第一个为.的情况
|| (s[k]=='0' && strlen(&s[k])>1) //以0开头的情况
|| !(atoi(&s[k])<=255 && atoi(&s[k])>=0)) //不符合区间范围
{
return false;
}
k = i+1;
++pCnt;
} else if(!(s[i]>='0' && s[i]<='9')) { //包含非 0-9或'.' 的情况
return false;
}
}
if(pCnt != 3+1) return false; //'.'不是3段,最后一个1是自己加的
return true;
}
/**
* 验证IP地址
* @param IP string字符串 一个IP地址字符串
* @return string字符串
*/
string solve(string IP) {
// write code here
if(type(IP)){
if(!checkV6(IP))
return "Neither";
return "IPv6";
} else {
if(!checkV4(IP))
return "Neither";
return "IPv4";
}
}
};
int main() {
std::cout << "[CPP IP检查测试]" << std::endl;
string input = "0.0.1.1";
SolutionIP solution;
string result = solution.solve(input);
cout << "input:\t" << input << endl;
cout << "result:\t" << result << endl;
return 0;
}
正则表达式
bool CheckIPAddrIsVaild(string str)
{
regex reg("(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))");
return regex_match(str, reg);
}
int main()
{
string ipstr;
while(cin>>ipstr){
bool res=CheckIPAddrIsVaild(ipstr);
if(res){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}
禁用/启用网卡
//netsh interface set interface name="接口名称" admin=DISABLE
system("netsh interface set interface name = ""Ethernet0"" admin = DISABLE");//禁用网卡
system("netsh interface set interface name = ""Ethernet0"" admin = ENABLE");//启用网卡
//运行该批处理命令需要管理员权限
//“接口名称”如果是中文则无法获得目标执行结果,如果想要成功执行,需要在“控制面板\网络和 Internet\网络连接”中将其重命名为不包含中文的名字.
判断台式电脑Or笔记本电脑
#include <Windows.h>
#include <stdio.h>
/*
台式机和笔记本的区别就在于是否有电源————读取电源信息的API提供返回值
BatterFlag:加载了电池的状况和包含的标志,当值为128和255时反应的是没电压或者读取不到电压,即可判断为台式电脑
*/
int main()
{
SYSTEM_POWER_STATUS a;
GetSystemPowerStatus(&a);
if (a.BatteryFlag == 128 && a.BatteryFlag == 255)
{
printf("台式电脑\n");
}
else
{
printf("笔记本电脑\n");
}
return 0;
}
获取CPU信息
#include <iostream>
#include <string>
#include <windows.h>
//存4个寄存器值
DWORD deax, debx, decx, dedx;
void initCpu(DWORD veax)
{
__asm
{
mov eax, veax
cpuid
mov deax, eax
mov debx, ebx
mov decx, ecx
mov dedx, edx
}
}
long getCpuFreq()
{
int start, over;
_asm
{
RDTSC
mov start, eax
}
Sleep(50);
_asm
{
RDTSC
mov over, eax
}
return (over - start) / 50000;
}
std::string getManufactureID()
{
char manuID[25];
memset(manuID, 0, sizeof(manuID));
initCpu(0);
memcpy(manuID + 0, &debx, 4); // copy to array
memcpy(manuID + 4, &dedx, 4);
memcpy(manuID + 8, &decx, 4);
return manuID;
}
std::string getCpuType()
{
const DWORD id = 0x80000002;
char cpuType[49];
memset(cpuType, 0, sizeof(cpuType));
for (DWORD t = 0; t < 3; t++){
initCpu(id + t);
memcpy(cpuType + 16 * t + 0, &deax, 4);
memcpy(cpuType + 16 * t + 4, &debx, 4);
memcpy(cpuType + 16 * t + 8, &decx, 4);
memcpy(cpuType + 16 * t + 12, &dedx, 4);
}
return cpuType;
}
void getCpuInfo(){
std::cout << "CPU主频: " << getCpuFreq() << "MHz" << std::endl;
std::cout << "CPU厂商: " << getManufactureID() << std::endl;
std::cout << "CPU类型: " << getCpuType() << std::endl;
}
void main(){
getCpuInfo();
system("pause");
return;
}
字符串切割
从完整路径中提取文件名、不带后缀的名字、后缀名
#include <iostream>
#include <string>
using namespace std;
void main()
{
string path = "C:\\Users\\Administrator\\Desktop\\text\\data.22.txt";
//1.获取不带路径的文件名
string::size_type iPos = path.find_last_of('\\') + 1;
string filename = path.substr(iPos, path.length() - iPos);
cout << filename << endl;
//2.获取不带后缀的文件名
string name = filename.substr(0, filename.rfind("."));
cout << name << endl;
//3.获取后缀名
string suffix_str = filename.substr(filename.find_last_of('.') + 1);
cout << suffix_str << endl;
}
要点:
- s.substr(0,5):获得字符串s中从第0位开始,长度为5的字符串;默认时的长度为从开始位置到尾。
- find_first_of(): 在字符串中查找第一个出现的字符c;
int find_first_of(char c, int start = 0)
查找字符串中第1个出现的c,由位置start开始。
如果有匹配,则返回匹配位置;否则,返回-1.
默认情况下,start为0,函数搜索整个字符串。
- find_last_of():在字符串中查找最后一个出现的字符c;
int find_last_of(char c):
查找字符串中最后一个出现的c。有匹配,则返回匹配位置;否则返回-1.
该搜索在字符末尾查找匹配,所以没有提供起始位置。
- find()正向查找,rfind()反向查找
(1)size_t find (const string& str, size_t pos = 0) const; //查找对象-string类对象
(2)size_t find (const char* s, size_t pos = 0) const; //查找对象-字符串
(3)size_t find (const char* s, size_t pos, size_t n) const; //查找对象-字符串的前n个字符
(4)size_t find (char c, size_t pos = 0) const; //查找对象–字符
结果:找到, 返回 第一个字符的索引; 没找到–返回 string::npos
字符串切割
#include <string.h>
#include <stdio.h>
int main()
{
char str[80] = "hello,world,hello";
const char s[2] = ",";
char* token;
char* next_token = NULL;
/* 获取第一个子字符串 */
token = strtok_s(str, s, &next_token);
/* 继续获取其他的子字符串 */
while (token != NULL) {
printf("%s\n", token);
token = strtok_s(NULL, s, &next_token);
}
return 0;
}
find用法-查找字符串
使用find_first_of如果在一个字符串str1中查找另一个字符串str2,如果str1中含有str2中的任何字符,则就会查找成功,而find则不同;
比如:
string str1(“I am change”);
string str2(“about”);
int k=str1.find_first_of(str2); //k返回的值是about这5个字符中任何一个首次在str1中出现的位置;
//the usage of find /find_first_of by heat_nan from ZZULI
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str1("Hi,every one! I am heat_nan from ZZULI. one");
string str2("heat_nan");
int k=str1.find(str2);
cout<<"The position of 'heat_nan' is "<<k<<endl;
int k1=str1.find("one");
cout<<"The postion of the first 'one' is "<<k1<<endl;
int k2=str1.find("one of",k1+1,3);
cout<<"The postion of the second 'one' is "<<k2<<endl;
int k3=str1.find_first_of("aeiou");//here k3=1
while(k3!=string::npos) //hint: here "string::npos"means find failed
{
str1[k3]='*';
k3=str1.find_first_of("aeiou",k3+1);
}
cout<<str1<<endl;
return 0;
}
使用样例:
string str1(“the usage of find can you use it”);
string str2(“the”);
上面定义出了两个字符串;
str1.find(str2); // 从串str1中查找时str2,返回str2中首个字符在str1中的地址
str1.find(str2,5); // 从str1的第5个字符开始查找str2
str1.find(“usage”); // 如果usage在str1中查找到,返回u在str1中的位置
str1.find(“o”); // 查找字符o并返回地址
str1.find(“of big”,2,2); // 从str1中的第二个字符开始查找of big的前两个字符
弹出CMD窗口
#include <io.h>
#include <fcntl.h>
void InitConsoleWindow()
{
AllocConsole();
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long)handle, _O_TEXT);
FILE * hf = _fdopen(hCrt, "w");
*stdout = *hf;
}
Usage:
InitConsoleWindow();
常用类型转换代码
CString头文件 #include
UNICODE_STRING to LPWSTR
// 将 UNICODE_STRING 转换为以 null 结尾的 LPWSTR
LPWSTR ConvertUnicodeStringToString(UNICODE_STRING str)
{
if (str.Buffer)
{
PWCHAR buffer = NEW_ARRAY(WCHAR, str.Length / sizeof(WCHAR) + 1);
libc_wmemcpy(buffer, str.Buffer, str.Length / sizeof(WCHAR));
buffer[str.Length / sizeof(WCHAR)] = L'\0';
return buffer;
}
else
{
return NULL;
}
}
LPCWSTR to LPCSTR
// 将 LPCWSTR 转换为以 null 结尾的 LPCSTR
LPCSTR ConvertStringToAString(LPCWSTR str)
{
PCHAR result = NULL;
int length = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
if (length > 0)
{
result = NEW_ARRAY(CHAR, length);
if (WideCharToMultiByte(CP_ACP, 0, str, -1, result, length, NULL, NULL) <= 0)
{
FREE(result);
result = NULL;
}
}
return result;
}
CString to char*
CString cstr = _T("test")
//声明标识
USES_CONVERSION;
//函数T2A和W2A均支持ATL和MFC中的字符
char * pFileName = T2A(cstr);
//char * pFileName = W2A(cstr); //也可实现转换
注意:有时候可能还需要添加引用#include <afxpriv.h>
char* to CString
char * pFileName = "test";
USES_CONVERSION;
CString s = A2T(pFileName);
//CString s = A2W(pFileName);
CString to String
//CT2A含义
//C:convert,转换的意思
//T:中间类型,如果定义了_UNICODE,则T表示W;如果定义了_MBCS,则T表示A
//W:宽字符串,也就是UNICODE
//A:ANSI字符串,也就是Muti-Byte。
CString c_name = _T("li");
//所以CT2A其实就是CW2A就是将Unicode转换为多字符集ASCII,也可写成CW2A
std::string str = CT2A(c_name.GetString());
String to CString
//CA2T含义
//C:convert,转换的意思
//A:ANSI字符串,也就是Muti-Byte
//2:to
//T:中间类型,如果定义了_UNICODE,则T表示W;如果定义了_MBCS,则T表示A
//W:宽字符串,也就是UNICODE
std::string name = "li";
CString c_name = CA2T(name.c_str()); //所以CA2T也就是CA2W就是将多字符集转换为宽字符UNICODE,也可写成CA2W。
String to Wchar_t
wchar_t *StringToWchar_t(const string& pStr)
{
const char* pCStr = pStr.c_str();
int pSize = MultiByteToWideChar(CP_OEMCP, 0, pCStr, strlen(pCStr) + 1, NULL, 0);
wchar_t *pWCStr = new wchar_t[pSize];
MultiByteToWideChar(CP_OEMCP, 0, pCStr, strlen(pCStr) + 1, pWCStr, pSize);
return pWCStr;
}
char to Wchar_t
wchar_t *charToWchar_t(const char* pCStr)
{
int pSize = MultiByteToWideChar(CP_OEMCP, 0, pCStr, strlen(pCStr) + 1, NULL, 0);
wchar_t *pWCStr = new wchar_t[pSize];
MultiByteToWideChar(CP_OEMCP, 0, pCStr, strlen(pCStr) + 1, pWCStr, pSize);
return pWCStr;
}
Wchar_t to char
char* Wchar_tTochar(wchar_t* pWCStrKey)
{
int pSize = WideCharToMultiByte(CP_OEMCP, 0, pWCStrKey, wcslen(pWCStrKey), NULL, 0, NULL, NULL);
char* pCStrKey = new char[pSize + 1];
WideCharToMultiByte(CP_OEMCP, 0, pWCStrKey, wcslen(pWCStrKey), pCStrKey, pSize, NULL, NULL);
pCStrKey[pSize] = '\0';
return pCStrKey;
}
UTF-8
读取文件UTF-8格式中文乱码
ifstream fin("C:\\Users\\nattevak\\source\\repos\\WaterMark\\Debug\\Remark.txt");
stringstream buffer;
buffer << fin.rdbuf();
string str(buffer.str());
string t = UTF8ToGB(str.c_str());
//string test = "jkdskGFDBDFgdssfs梵蒂冈地方jbg ";
//CString str1( StringToWString(test).c_str() );
MessageBox(StringToWchar_t(t));
将UTF-8转为GBK
string UTF8ToGB(const char* str)
{
string result;
WCHAR* strSrc;
LPSTR szRes;
//获得临时变量的大小
int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
strSrc = new WCHAR[i + 1];
MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);
//获得临时变量的大小
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
szRes = new CHAR[i + 1];
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);
result = szRes;
delete[]strSrc;
delete[]szRes;
return result;
}
自实现函数
文件操作
删除文件
// DeleteFile
BOOL CustomDeleteFile(WCHAR* filePath) {
if (filePath == NULL) {
return FALSE;
}
HANDLE fileHandle = CreateFileW(
filePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE,
NULL
);
if (fileHandle == INVALID_HANDLE_VALUE) {
return FALSE;
}
// 关闭文件句柄以触发删除操作
CloseHandle(fileHandle);
return TRUE;
}
移动文件
#include <iostream>
#include <string>
#include <Windows.h>
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")
NTSTATUS(__stdcall *NtSetInformationFile)(
_In_ HANDLE FileHandle,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID FileInformation,
_In_ ULONG Length,
_In_ FILE_INFORMATION_CLASS FileInformationClass
);
bool MoveFileNative(const std::wstring& srcPath, const std::wstring& destPath) {
// 打开源文件
HANDLE hFile = CreateFileW(srcPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
std::wcerr << L"打开源文件失败。" << std::endl;
return false;
}
// 获取NtSetInformationFile函数的地址
NtSetInformationFile = (NTSTATUS(__stdcall*)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS))GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtSetInformationFile");
if (!NtSetInformationFile) {
std::wcerr << L"获取NtSetInformationFile函数失败。" << std::endl;
CloseHandle(hFile);
return false;
}
// 初始化FILE_RENAME_INFORMATION结构体
size_t renameInfoSize = sizeof(FILE_RENAME_INFORMATION) + destPath.size() * sizeof(WCHAR);
FILE_RENAME_INFORMATION* renameInfo = (FILE_RENAME_INFORMATION*)malloc(renameInfoSize);
if (!renameInfo) {
std::wcerr << L"分配内存失败。" << std::endl;
CloseHandle(hFile);
return false;
}
ZeroMemory(renameInfo, renameInfoSize);
renameInfo->ReplaceIfExists = FALSE;
renameInfo->RootDirectory = nullptr;
renameInfo->FileNameLength = static_cast<ULONG>(destPath.size() * sizeof(WCHAR));
memcpy(renameInfo->FileName, destPath.c_str(), destPath.size() * sizeof(WCHAR));
// 调用NtSetInformationFile执行文件移动操作
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS status = NtSetInformationFile(hFile, &ioStatusBlock, renameInfo, static_cast<ULONG>(renameInfoSize), FileRenameInformation);
// 释放内存并关闭文件句柄
free(renameInfo);
CloseHandle(hFile);
// 检查操作是否成功
if (status != STATUS_SUCCESS) {
std::wcerr << L"移动文件失败,NTSTATUS: 0x" << std::hex << status << std::endl;
return false;
}
return true;
}
文档信息
- 本文作者:Nattevak
- 本文链接:https://HLuKT.github.io/2023/04/23/Windows%E5%B8%B8%E7%94%A8%E5%B7%A5%E5%85%B7%E4%BB%A3%E7%A0%81/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)