常用类型

1. 字符串类型

  • WCHAR: 宽字符类型,与 wchar_t 类似,用于表示 Unicode 字符。

  • LPWSTR: 指向宽字符(WCHAR)字符串的指针,表示一个以 null 结尾的宽字符字符串(类似于 wchar_t*)。

  • LPCWSTR: 指向常量宽字符字符串的指针(const wchar_t*),通常用于函数参数,表示输入的宽字符字符串。

  • LPSTR: 指向一个以 null 结尾的 ANSI 字符串的指针(类似于 char*)。

  • LPCSTR: 指向常量 ANSI 字符串的指针(const char*),通常用于函数参数,表示输入的 ANSI 字符串。

  • TCHAR: 在 Unicode 项目中表示 wchar_t,在 ANSI 项目中表示 char。主要用于跨平台的字符处理。

2. 整数类型

  • BYTE: 8 位无符号整数,等同于 unsigned char

  • WORD: 16 位无符号整数,等同于 unsigned short

  • DWORD: 32 位无符号整数,等同于 unsigned long

  • INT: 与 int 等价,通常是 32 位的整数。

  • UINT: 32 位无符号整数,等同于 unsigned int

  • LONG: 32 位有符号整数,等同于 long

  • ULONG: 32 位无符号整数,等同于 unsigned long

3. 指针类型

  • PVOID: 泛型指针类型,类似于 void*

  • LPVOID: 指向任意类型数据的指针,类似于 void*

  • HANDLE: 用于表示各种资源(如窗口、文件、线程等)的句柄,通常是一个指针或整数类型。

  • HINSTANCE: 表示应用程序实例的句柄,通常用于标识加载到内存中的模块。

4. 布尔类型

  • BOOL: Windows 定义的布尔类型,通常用 TRUEFALSE 表示。

  • BOOLEAN: 8 位布尔类型,通常用 TRUEFALSE 表示。

5. 结构体类型

  • POINT: 表示二维坐标的结构体,包含 xy 两个成员。

  • RECT: 表示矩形区域的结构体,包含 lefttoprightbottom 四个成员。

  • SIZE: 表示宽度和高度的结构体,包含 cxcy 两个成员。

6. 特殊类型

  • HRESULT: 用于返回函数执行结果的 32 位值,包含错误码和状态信息。

  • LRESULT: 用于表示窗口消息处理函数的返回值。

  • COLORREF: 用于表示颜色值的 32 位整数,包含 RGB 颜色信息。

修改注册表实现开机自启

#include <windows.h>
#include <io.h>
#include <stdio.h>

// 添加开机启动项的函数
void AddToSystem(const char* softwareName) {
    HKEY hKey;
    char CurrentPath[MAX_PATH] = { "" };
    char SystemPath[MAX_PATH] = { "" };
    long ret = 0;
    LPSTR FileNewName;
    LPSTR FileCurrentName;
    DWORD type = REG_SZ;
    DWORD size = MAX_PATH;
    LPCTSTR Rgspath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";

    // 获取系统目录路径
    GetSystemDirectory(SystemPath, size);

    // 获取当前模块(可执行文件)的文件路径
    GetModuleFileName(NULL, CurrentPath, size);

    // 设置当前文件名和新的文件名
    FileCurrentName = CurrentPath;
    FileNewName = lstrcat(SystemPath, "\\");
    FileNewName = lstrcat(FileNewName, softwareName);

    struct _finddata_t Steal;

    // 打印初始ret值
    printf("retl = %d\n", ret);

    // 检查文件是否已经存在(即是否已经安装)
    if (_findfirst(FileNewName, &Steal) != -1) {
        return; // 如果文件已经存在,则返回
    }

    // 打印ret值
    printf("ret2 = %d", ret);

    // 显示消息框,提示用户是否允许自动启动
    int ihow = MessageBox(0, "是 将开启自动启动\n否 则取消", "警 告", MB_YESNOCANCEL | MB_ICONWARNING | MB_TOPMOST);

    // 如果用户选择取消,则退出程序
    if (ihow == IDCANCEL) {
        exit(0);
    }
    // 如果用户选择否,则返回,不做任何修改
    if (ihow == IDNO) {
        return;
    }

    // 复制当前文件到新的位置
    ret = CopyFile(FileCurrentName, FileNewName, TRUE);
    if (!ret) {
        return; // 如果复制失败,则返回
    }

    // 打印ret值
    printf("ret = %d\n", ret);

    // 打开注册表键
    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Rgspath, 0, KEY_WRITE, &hKey);
    if (ret != ERROR_SUCCESS) {
        return; // 如果打开注册表键失败,则返回
    }

    // 设置注册表值,添加程序到开机自启动项
    ret = RegSetValueEx(hKey, softwareName, 0, type, (const unsigned char*)FileNewName, strlen(FileNewName) + 1);
    if (ret != ERROR_SUCCESS) {
        RegCloseKey(hKey);
        return; // 如果设置注册表值失败,则关闭注册表键并返回
    }

    // 关闭注册表键
    RegCloseKey(hKey);
}



// 关闭开机启动项的函数
void RemoveFromSystem(const char* softwareName) {
    HKEY hKey;
    long ret;
    LPCTSTR Rgspath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";

    // 打开注册表键
    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Rgspath, 0, KEY_WRITE, &hKey);
    if (ret != ERROR_SUCCESS) {
        return; // 如果打开注册表键失败,则返回
    }

    // 删除指定的软件的注册表值
    ret = RegDeleteValue(hKey, softwareName);
    if (ret != ERROR_SUCCESS) {
        RegCloseKey(hKey);
        return; // 如果删除注册表值失败,则关闭注册表键并返回
    }

    // 关闭注册表键
    RegCloseKey(hKey);

    // 获取系统目录路径
    char SystemPath[MAX_PATH] = { "" };
    GetSystemDirectory(SystemPath, MAX_PATH);

    // 拼接软件的路径
    char FileNewName[MAX_PATH];
    strcpy(FileNewName, SystemPath);
    strcat(FileNewName, "\\");
    strcat(FileNewName, softwareName);

    // 删除软件文件
    if (_unlink(FileNewName) == -1) {
        printf("Failed to delete the file: %s\n", FileNewName);
    }
}

int main() {
    // 调用函数并传入软件名
    AddToSystem("MySoftware.exe");

    // 调用函数删除开机启动项
    RemoveFromSystem("MySoftware.exe");

    return 0;
}

代码说明:

  1. RemoveFromSystem 函数:

    • 打开注册表键:打开注册表键HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run

    • 删除注册表值:删除与传入的软件名对应的注册表值,以关闭开机自启动。

    • 删除软件文件:获取系统目录路径,并删除对应的软件文件。

  2. AddToSystem 函数:与之前的版本相同,只是用来添加软件到开机启动项。

main函数中,首先调用AddToSystem函数添加开机启动项,然后调用RemoveFromSystem函数删除开机启动项。这样可以测试两者的功能是否正常。

网络编程初始化

#include <winsock2.h>
#include <stdio.h>

// 初始化网络库函数
int Init_SOCKNET() {
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    // 请求使用的 Winsock 版本为 2.2
    wVersionRequested = MAKEWORD(2, 2);

    // 初始化 Winsock 库
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        // 如果初始化失败,输出错误信息并返回错误码
        printf("WSAStartup failed with error: %d\n", err);
        return err;
    }

    // 检查 Winsock 库是否支持 2.2 版本
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        // 如果版本不匹配,输出错误信息并清理 Winsock 库
        printf("Could not find a usable version of Winsock.dll\n");
        WSACleanup();
        return -1;
    }

    // 初始化成功,返回 0
    printf("Winsock 2.2 initialized successfully.\n");
    return 0;
}

int main() {
    // 调用初始化网络库函数
    int result = Init_SOCKNET();
    if (result != 0) {
        printf("Failed to initialize network library.\n");
        return result;
    }

    // 进行其他网络编程操作
    // ...

    // 清理 Winsock 库
    WSACleanup();
    return 0;
}

默认管理员运行

#include <windows.h>
#include <shellapi.h>
#include <stdio.h>

// 函数声明
BOOL IsRunAsAdmin();
void RestartAsAdmin();

int main() {
    if (!IsRunAsAdmin()) {
        RestartAsAdmin();
        return 0;
    }

    // 如果已经是管理员权限,继续执行程序
    printf("Program is running as administrator.\n");

    // 您的其他代码...
    // ...

    return 0;
}

// 检查程序是否以管理员权限运行
BOOL IsRunAsAdmin() {
    BOOL isAdmin = FALSE;
    PSID adminGroup = NULL;

    // 创建一个SID标识管理员组
    SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
    if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) {
        // 检查进程令牌是否具有管理员组
        CheckTokenMembership(NULL, adminGroup, &isAdmin);
        FreeSid(adminGroup);
    }

    return isAdmin;
}

// 以管理员权限重新启动程序
void RestartAsAdmin() {
    wchar_t szPath[MAX_PATH];

    // 获取当前进程的文件名
    if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) {
        // 设置ShellExecuteEx参数
        SHELLEXECUTEINFO sei = { sizeof(sei) };
        sei.lpVerb = L"runas";
        sei.lpFile = szPath;
        sei.hwnd = NULL;
        sei.nShow = SW_NORMAL;

        // 重新启动程序并以管理员权限运行
        if (!ShellExecuteEx(&sei)) {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_CANCELLED) {
                // 用户取消了UAC提示
                printf("User cancelled the UAC prompt.\n");
            } else {
                printf("ShellExecuteEx failed with error: %lu\n", dwError);
            }
        }
    }
}

隐藏进程

void HideMyself() {
	//拿到当前窗口句柄
	HWND hwnd = GetForegroundWindow();
	ShowWindow(hwnd, SW_HIDE);
}

遍历文件

#include <windows.h>
#include <stdio.h>

// 函数声明
void TraverseDirectory(const char* directoryPath);

int main() {
    const char* directoryPath = "C:\\your\\directory\\path";
    TraverseDirectory(directoryPath);
    return 0;
}

// 遍历目录的函数
void TraverseDirectory(const char* directoryPath) {
    WIN32_FIND_DATA findFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    char dirPath[MAX_PATH];
    char fullPath[MAX_PATH];

    // 构建搜索路径
    snprintf(dirPath, MAX_PATH, "%s\\*", directoryPath);

    hFind = FindFirstFile(dirPath, &findFileData);

    if (hFind == INVALID_HANDLE_VALUE) {
        printf("FindFirstFile failed with error %lu\n", GetLastError());
        return;
    }

    do {
        // 忽略 "." 和 ".." 目录
        if (strcmp(findFileData.cFileName, ".") != 0 && strcmp(findFileData.cFileName, "..") != 0) {
            snprintf(fullPath, MAX_PATH, "%s\\%s", directoryPath, findFileData.cFileName);
            if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                // 如果是目录,递归遍历
                printf("Directory: %s\n", fullPath);
                TraverseDirectory(fullPath);
            } else {
                // 如果是文件,打印文件路径
                printf("File: %s\n", fullPath);
            }
        }
    } while (FindNextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
}