Skip to content

Instantly share code, notes, and snippets.

@KuRRe8
Last active May 26, 2025 00:36
Show Gist options
  • Save KuRRe8/1051ce47444f7b194d7d5e27f53f91fd to your computer and use it in GitHub Desktop.
Save KuRRe8/1051ce47444f7b194d7d5e27f53f91fd to your computer and use it in GitHub Desktop.
windows related knowledge

My Windows Notes

1 WINAPI

1.1 KnownFolderID

Windows中包含很多约定的路径,比如%APPDATA% %USERPROFILE%,或者一些库路径,文档,图片,视频。在Windows编程实践中, 应该使用knownfolderid 来固定查找位置。

import ctypes
from ctypes import wintypes
import os

# Define GUID structure
class GUID(ctypes.Structure):
    _fields_ = [
        ("Data1", wintypes.DWORD),
        ("Data2", wintypes.WORD),
        ("Data3", wintypes.WORD),
        ("Data4", wintypes.BYTE * 8)
    ]

# KnownFolderID GUIDs
FOLDERID_RoamingAppData = GUID(0x3EB685DB, 0x65F9, 0x4CF6, (ctypes.c_ubyte * 8)(0xA0,0x3A,0xE3,0xEF,0x65,0x72,0x9F,0x3D))
FOLDERID_LocalAppData   = GUID(0xF1B32785, 0x6FBA, 0x4FCF, (ctypes.c_ubyte * 8)(0x9D,0x55,0x7B,0x8E,0x7F,0x15,0x70,0x91))
FOLDERID_ProgramData    = GUID(0x62AB5D82, 0xFDC1, 0x4DC3, (ctypes.c_ubyte * 8)(0xA9,0xDD,0x07,0x0D,0x1D,0x49,0x5D,0x97))
FOLDERID_Documents      = GUID(0xFDD39AD0, 0x238F, 0x46AF, (ctypes.c_ubyte * 8)(0xAD,0xB4,0x6C,0x85,0x48,0x03,0x69,0xC7))
FOLDERID_ProgramFiles   = GUID(0x905E63B6, 0xC1BF, 0x494E, (ctypes.c_ubyte * 8)(0xB2,0x9C,0x65,0xB7,0x32,0xD3,0xD2,0x1A))
FOLDERID_ProgramFilesX64 = GUID(0x6D809377, 0x6AF0, 0x444B, (ctypes.c_ubyte * 8)(0x89,0x57,0xA3,0x77,0x3F,0x02,0x20,0x0E))

# SHGetKnownFolderPath prototype
SHGetKnownFolderPath = ctypes.windll.shell32.SHGetKnownFolderPath
SHGetKnownFolderPath.argtypes = [ctypes.POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p)]
SHGetKnownFolderPath.restype = wintypes.HRESULT

def get_known_folder_path(folder_id):
    path_ptr = ctypes.c_wchar_p()
    hr = SHGetKnownFolderPath(ctypes.byref(folder_id), 0, 0, ctypes.byref(path_ptr))
    if hr != 0:
        raise ctypes.WinError(hr)
    path = path_ptr.value
    ctypes.windll.ole32.CoTaskMemFree(path_ptr)
    return path

if __name__ == "__main__":
    print("FOLDERID_RoamingAppData:", get_known_folder_path(FOLDERID_RoamingAppData))
    print("FOLDERID_LocalAppData:", get_known_folder_path(FOLDERID_LocalAppData))
    print("FOLDERID_ProgramData:", get_known_folder_path(FOLDERID_ProgramData))
    print("FOLDERID_Documents:", get_known_folder_path(FOLDERID_Documents))
    print("FOLDERID_ProgramFiles:", get_known_folder_path(FOLDERID_ProgramFiles))
    print("FOLDERID_ProgramFilesX64:", get_known_folder_path(FOLDERID_ProgramFilesX64))
    print("TEMP:", os.environ.get("TEMP"))
#include <windows.h>
#include <shlobj.h>
#include <iostream>
#include <string>

void print_known_folder(const wchar_t* name, const KNOWNFOLDERID& folderId) {
    PWSTR path = nullptr;
    HRESULT hr = SHGetKnownFolderPath(folderId, 0, NULL, &path);
    if (SUCCEEDED(hr)) {
        std::wcout << name << L": " << path << std::endl;
        CoTaskMemFree(path);
    } else {
        std::wcout << name << L": <Failed to get path>" << std::endl;
    }
}

int main() {
    print_known_folder(L"FOLDERID_RoamingAppData", FOLDERID_RoamingAppData);
    print_known_folder(L"FOLDERID_LocalAppData", FOLDERID_LocalAppData);
    print_known_folder(L"FOLDERID_ProgramData", FOLDERID_ProgramData);
    print_known_folder(L"FOLDERID_Documents", FOLDERID_Documents);
    print_known_folder(L"FOLDERID_ProgramFiles", FOLDERID_ProgramFiles);
    print_known_folder(L"FOLDERID_ProgramFilesX64", FOLDERID_ProgramFilesX64);
    wchar_t* temp = _wgetenv(L"TEMP");
    std::wcout << L"TEMP: " << (temp ? temp : L"<not found>") << std::endl;
    return 0;
}

1.2 Registry

一个应用程序通常往注册表的HKCU\Software内写数据,规范是外层为公司名,内部是产品名,然后是自组织的设置条目。

import winreg

company = "MyExampleCompany"
product = "MyExampleProduct"
settings = {
    "SettingA": 123,
    "SettingB": "hello",
    "SettingC": 1.23
}

key_path = fr"Software\\{company}\\{product}"

with winreg.CreateKey(winreg.HKEY_CURRENT_USER, key_path) as key:
    for name, value in settings.items():
        if isinstance(value, int):
            winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
        elif isinstance(value, float):
            # 注册表没有 float 类型,通常以字符串形式存储
            winreg.SetValueEx(key, name, 0, winreg.REG_SZ, str(value))
        else:
            winreg.SetValueEx(key, name, 0, winreg.REG_SZ, value)
print(f"Wrote settings to HKEY_CURRENT_USER\\{key_path}")
#include <windows.h>
#include <string>
#include <iostream>

int main() {
    const wchar_t* company = L"MyExampleCompany";
    const wchar_t* product = L"MyExampleProduct";
    std::wstring keyPath = std::wstring(L"Software\\") + company + L"\\" + product;

    HKEY hKey;
    LONG result = RegCreateKeyExW(
        HKEY_CURRENT_USER,
        keyPath.c_str(),
        0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL
    );
    if (result != ERROR_SUCCESS) {
        std::wcerr << L"Failed to create/open registry key!" << std::endl;
        return 1;
    }

    DWORD settingA = 123;
    std::wstring settingB = L"hello";
    std::wstring settingC = L"1.23"; // float as string

    RegSetValueExW(hKey, L"SettingA", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&settingA), sizeof(settingA));
    RegSetValueExW(hKey, L"SettingB", 0, REG_SZ, reinterpret_cast<const BYTE*>(settingB.c_str()), (settingB.size() + 1) * sizeof(wchar_t));
    RegSetValueExW(hKey, L"SettingC", 0, REG_SZ, reinterpret_cast<const BYTE*>(settingC.c_str()), (settingC.size() + 1) * sizeof(wchar_t));

    RegCloseKey(hKey);
    std::wcout << L"Wrote settings to HKEY_CURRENT_USER\\" << keyPath << std::endl;
    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment