[{"data":1,"prerenderedAt":1392},["ShallowReactive",2],{"doc-\u002Fdocs\u002Fapi\u002Feduwin-util-api":3},{"id":4,"title":5,"body":6,"description":23,"extension":1386,"meta":1387,"navigation":184,"path":1388,"seo":1389,"stem":1390,"__hash__":1391},"content\u002Fdocs\u002Fapi\u002Feduwin-util-api.md","eduwin 工具 API",{"type":7,"value":8,"toc":1368},"minimark",[9,13,17,34,42,51,62,71,80,89,96,118,133,160,198,201,204,213,216,218,222,231,249,264,271,273,276,280,295,313,329,344,347,362,378,392,395,487,541,545,554,571,574,609,611,614,617,656,668,670,673,698,724,730,743,749,821,824,857,872,911,914,977,987,1027,1030,1060,1074,1118,1121,1136,1146,1170,1173,1237,1243,1263,1266,1291,1309,1322,1328,1353,1356,1364],[10,11,5],"h1",{"id":12},"eduwin-工具-api",[14,15,16],"h2",{"id":16},"数字与字符串工具",[18,19,24],"pre",{"className":20,"code":21,"language":22,"meta":23,"style":23},"language-c shiki shiki-themes github-light github-dark","int rand_int(int min, int max);\n","c","",[25,26,27],"code",{"__ignoreMap":23},[28,29,32],"span",{"class":30,"line":31},"line",1,[28,33,21],{},[35,36,37,38,41],"p",{},"返回 ",[25,39,40],{},"[min, max]"," 闭区间的随机整数。",[18,43,45],{"className":20,"code":44,"language":22,"meta":23,"style":23},"const WCHAR *itow(int value);\n",[25,46,47],{"__ignoreMap":23},[28,48,49],{"class":30,"line":31},[28,50,44],{},[35,52,53,54,57,58,61],{},"整数 → 宽字符串。如 ",[25,55,56],{},"itow(42)"," 返回 ",[25,59,60],{},"L\"42\"","。",[18,63,65],{"className":20,"code":64,"language":22,"meta":23,"style":23},"const WCHAR *ftow(double value);\n",[25,66,67],{"__ignoreMap":23},[28,68,69],{"class":30,"line":31},[28,70,64],{},[35,72,73,74,57,77,61],{},"小数 → 宽字符串。如 ",[25,75,76],{},"ftow(3.14)",[25,78,79],{},"L\"3.14\"",[18,81,83],{"className":20,"code":82,"language":22,"meta":23,"style":23},"void str_concat(WCHAR *dest, int size, ...);\n",[25,84,85],{"__ignoreMap":23},[28,86,87],{"class":30,"line":31},[28,88,82],{},[35,90,91,92,95],{},"拼接多个宽字符串，最后一个参数必须是 ",[25,93,94],{},"NULL"," 表示结束。",[18,97,99],{"className":20,"code":98,"language":22,"meta":23,"style":23},"WCHAR buf[64];\nstr_concat(buf, 64, L\"你点击了 \", itow(count), L\" 次\", NULL);\nset_text(label, buf);\n",[25,100,101,106,112],{"__ignoreMap":23},[28,102,103],{"class":30,"line":31},[28,104,105],{},"WCHAR buf[64];\n",[28,107,109],{"class":30,"line":108},2,[28,110,111],{},"str_concat(buf, 64, L\"你点击了 \", itow(count), L\" 次\", NULL);\n",[28,113,115],{"class":30,"line":114},3,[28,116,117],{},"set_text(label, buf);\n",[18,119,121],{"className":20,"code":120,"language":22,"meta":23,"style":23},"void str_format(WCHAR *buf, int size, const WCHAR *fmt, ...);\nvoid str_format_a(char *buf, int size, const char *fmt, ...);\n",[25,122,123,128],{"__ignoreMap":23},[28,124,125],{"class":30,"line":31},[28,126,127],{},"void str_format(WCHAR *buf, int size, const WCHAR *fmt, ...);\n",[28,129,130],{"class":30,"line":108},[28,131,132],{},"void str_format_a(char *buf, int size, const char *fmt, ...);\n",[35,134,135,136,139,140,143,144,147,148,151,152,155,156,159],{},"格式化字符串到 ",[25,137,138],{},"buf","，用法类似 ",[25,141,142],{},"printf","，自动截断不会溢出。",[25,145,146],{},"str_format"," 输出到宽字符串（",[25,149,150],{},"WCHAR","），",[25,153,154],{},"str_format_a"," 输出到 UTF-8 字符串（",[25,157,158],{},"char","）。",[18,161,163],{"className":20,"code":162,"language":22,"meta":23,"style":23},"WCHAR buf[64];\nstr_format(buf, 64, L\"Client: %d x %d\", w, h);  \u002F* buf = L\"Client: 682 x 453\" *\u002F\nstr_format(buf, 64, L\"%.1f%%\", 95.7f);          \u002F* buf = L\"95.7%\" *\u002F\n\nchar buf_a[64];\nstr_format_a(buf_a, 64, \"{\\\"result\\\":%d}\", 42); \u002F* buf_a = {\"result\":42} *\u002F\n",[25,164,165,169,174,179,186,192],{"__ignoreMap":23},[28,166,167],{"class":30,"line":31},[28,168,105],{},[28,170,171],{"class":30,"line":108},[28,172,173],{},"str_format(buf, 64, L\"Client: %d x %d\", w, h);  \u002F* buf = L\"Client: 682 x 453\" *\u002F\n",[28,175,176],{"class":30,"line":114},[28,177,178],{},"str_format(buf, 64, L\"%.1f%%\", 95.7f);          \u002F* buf = L\"95.7%\" *\u002F\n",[28,180,182],{"class":30,"line":181},4,[28,183,185],{"emptyLinePlaceholder":184},true,"\n",[28,187,189],{"class":30,"line":188},5,[28,190,191],{},"char buf_a[64];\n",[28,193,195],{"class":30,"line":194},6,[28,196,197],{},"str_format_a(buf_a, 64, \"{\\\"result\\\":%d}\", 42); \u002F* buf_a = {\"result\":42} *\u002F\n",[199,200],"hr",{},[14,202,203],{"id":203},"剪贴板",[18,205,207],{"className":20,"code":206,"language":22,"meta":23,"style":23},"void clipboard_copy(const WCHAR *text);\n",[25,208,209],{"__ignoreMap":23},[28,210,211],{"class":30,"line":31},[28,212,206],{},[35,214,215],{},"将文本复制到系统剪贴板。",[199,217],{},[14,219,221],{"id":220},"base64-解码","Base64 解码",[18,223,225],{"className":20,"code":224,"language":22,"meta":23,"style":23},"int base64_decode(const char *in, int in_len, unsigned char *out);\n",[25,226,227],{"__ignoreMap":23},[28,228,229],{"class":30,"line":31},[28,230,224],{},[35,232,233,234,237,238,241,242,245,246,159],{},"解码 Base64 字符串为原始字节。",[25,235,236],{},"in_len"," 传入输入字符串长度（用 ",[25,239,240],{},"strlen","），返回值是输出的字节数。",[25,243,244],{},"out"," 缓冲区需足够大（最大约为 ",[25,247,248],{},"in_len * 3 \u002F 4",[18,250,252],{"className":20,"code":251,"language":22,"meta":23,"style":23},"unsigned char data[1024];\nint len = base64_decode(\"SGVsbG8=\", 8, data);  \u002F\u002F len=5, data=\"Hello\"\n",[25,253,254,259],{"__ignoreMap":23},[28,255,256],{"class":30,"line":31},[28,257,258],{},"unsigned char data[1024];\n",[28,260,261],{"class":30,"line":108},[28,262,263],{},"int len = base64_decode(\"SGVsbG8=\", 8, data);  \u002F\u002F len=5, data=\"Hello\"\n",[35,265,266,267,270],{},"内部在 ",[25,268,269],{},"eduwin_d3d"," 的 glTF 加载器中使用，解码 data URI 中的 base64 数据。",[199,272],{},[14,274,275],{"id":275},"文件读写",[277,278,279],"h3",{"id":279},"文本文件读写",[18,281,283],{"className":20,"code":282,"language":22,"meta":23,"style":23},"int read_text_file(const WCHAR *filepath, WCHAR *buf, int size);\nint write_text_file(const WCHAR *filepath, const WCHAR *text);\n",[25,284,285,290],{"__ignoreMap":23},[28,286,287],{"class":30,"line":31},[28,288,289],{},"int read_text_file(const WCHAR *filepath, WCHAR *buf, int size);\n",[28,291,292],{"class":30,"line":108},[28,293,294],{},"int write_text_file(const WCHAR *filepath, const WCHAR *text);\n",[35,296,297,300,301,305,306,309,310,61],{},[25,298,299],{},"read_text_file"," 读取文本文件内容到宽字符串缓冲区。自动以 ",[302,303,304],"strong",{},"UTF-8"," 编码读取（兼容含 BOM 的文件）。成功返回读取的字符数（不含末尾 ",[25,307,308],{},"\\0","），失败返回 ",[25,311,312],{},"-1",[35,314,315,318,319,321,322,325,326,61],{},[25,316,317],{},"write_text_file"," 将宽字符串写入文本文件，编码为 ",[302,320,304],{},"（含 BOM）。成功返回 ",[25,323,324],{},"1","，失败返回 ",[25,327,328],{},"0",[18,330,332],{"className":20,"code":331,"language":22,"meta":23,"style":23},"WCHAR buf[1024];\nint n = read_text_file(L\"data.txt\", buf, 1024);\n",[25,333,334,339],{"__ignoreMap":23},[28,335,336],{"class":30,"line":31},[28,337,338],{},"WCHAR buf[1024];\n",[28,340,341],{"class":30,"line":108},[28,342,343],{},"int n = read_text_file(L\"data.txt\", buf, 1024);\n",[277,345,346],{"id":346},"二进制文件读写",[18,348,350],{"className":20,"code":349,"language":22,"meta":23,"style":23},"int read_bin_file(const WCHAR *filepath, void *buf, int elem_size, int max_count);\nint write_bin_file(const WCHAR *filepath, void *buf, int elem_size, int count);\n",[25,351,352,357],{"__ignoreMap":23},[28,353,354],{"class":30,"line":31},[28,355,356],{},"int read_bin_file(const WCHAR *filepath, void *buf, int elem_size, int max_count);\n",[28,358,359],{"class":30,"line":108},[28,360,361],{},"int write_bin_file(const WCHAR *filepath, void *buf, int elem_size, int count);\n",[35,363,364,367,368,371,372,375,376,61],{},[25,365,366],{},"read_bin_file"," 从二进制文件中读取数据到缓冲区。",[25,369,370],{},"elem_size"," 为每个元素的字节数，",[25,373,374],{},"max_count"," 为最多读取多少个元素。成功返回实际读取的元素数，失败返回 ",[25,377,312],{},[35,379,380,383,384,387,388,325,390,61],{},[25,381,382],{},"write_bin_file"," 将缓冲区数据写入二进制文件。",[25,385,386],{},"count"," 为要写入的元素个数。成功返回 ",[25,389,324],{},[25,391,328],{},[35,393,394],{},"常用于读写结构体或结构体数组：",[18,396,398],{"className":20,"code":397,"language":22,"meta":23,"style":23},"typedef struct {\n    int id;\n    WCHAR name[32];\n    int score;\n} Student;\n\nStudent students[3] = {\n    {1001, L\"张三\", 85},\n    {1002, L\"李四\", 92},\n    {1003, L\"王五\", 78}\n};\n\nwrite_bin_file(L\"students.bin\", students, sizeof(Student), 3);\n\nStudent buf[3];\nint n = read_bin_file(L\"students.bin\", buf, sizeof(Student), 3);\n",[25,399,400,405,410,415,420,425,429,435,441,447,453,459,464,470,475,481],{"__ignoreMap":23},[28,401,402],{"class":30,"line":31},[28,403,404],{},"typedef struct {\n",[28,406,407],{"class":30,"line":108},[28,408,409],{},"    int id;\n",[28,411,412],{"class":30,"line":114},[28,413,414],{},"    WCHAR name[32];\n",[28,416,417],{"class":30,"line":181},[28,418,419],{},"    int score;\n",[28,421,422],{"class":30,"line":188},[28,423,424],{},"} Student;\n",[28,426,427],{"class":30,"line":194},[28,428,185],{"emptyLinePlaceholder":184},[28,430,432],{"class":30,"line":431},7,[28,433,434],{},"Student students[3] = {\n",[28,436,438],{"class":30,"line":437},8,[28,439,440],{},"    {1001, L\"张三\", 85},\n",[28,442,444],{"class":30,"line":443},9,[28,445,446],{},"    {1002, L\"李四\", 92},\n",[28,448,450],{"class":30,"line":449},10,[28,451,452],{},"    {1003, L\"王五\", 78}\n",[28,454,456],{"class":30,"line":455},11,[28,457,458],{},"};\n",[28,460,462],{"class":30,"line":461},12,[28,463,185],{"emptyLinePlaceholder":184},[28,465,467],{"class":30,"line":466},13,[28,468,469],{},"write_bin_file(L\"students.bin\", students, sizeof(Student), 3);\n",[28,471,473],{"class":30,"line":472},14,[28,474,185],{"emptyLinePlaceholder":184},[28,476,478],{"class":30,"line":477},15,[28,479,480],{},"Student buf[3];\n",[28,482,484],{"class":30,"line":483},16,[28,485,486],{},"int n = read_bin_file(L\"students.bin\", buf, sizeof(Student), 3);\n",[488,489,490,495],"blockquote",{},[35,491,492],{},[302,493,494],{},"注意事项：",[496,497,498,505,522,528],"ol",{},[499,500,501,504],"li",{},[302,502,503],{},"不可跨平台","——结构体内存布局（对齐、填充字节）在不同编译器下可能不同。在 eduwin（MSVC x64）环境下读写无问题。",[499,506,507,510,511,514,515,518,519,159],{},[302,508,509],{},"不能包含指针","——结构体里有 ",[25,512,513],{},"char *"," 或 ",[25,516,517],{},"WCHAR *"," 指针时，只会写入指针地址值而不是指向的字符串内容。应改用固定大小的字符数组（如 ",[25,520,521],{},"WCHAR name[32]",[499,523,524,527],{},[302,525,526],{},"路径用宽字符串","——与 eduwin 其他文件 API 一致。",[499,529,530,533,534,536,537,540],{},[302,531,532],{},"防止缓冲区溢出","——",[25,535,138],{}," 必须足够大以容纳 ",[25,538,539],{},"elem_size * max_count"," 字节。",[277,542,544],{"id":543},"二进制文件读取动态分配","二进制文件读取（动态分配）",[18,546,548],{"className":20,"code":547,"language":22,"meta":23,"style":23},"unsigned char* read_bin_file_alloc(const char *path, int *out_len);\n",[25,549,550],{"__ignoreMap":23},[28,551,552],{"class":30,"line":31},[28,553,547],{},[35,555,556,557,560,561,564,565,568,569,61],{},"将整个文件一次性读入堆内存，自动以 ",[25,558,559],{},"malloc"," 分配缓冲区。",[25,562,563],{},"out_len"," 返回文件字节数。调用方需用 ",[25,566,567],{},"free()"," 释放返回的缓冲区。失败返回 ",[25,570,94],{},[35,572,573],{},"常用于需要将整个文件加载到内存的场景，如图片文件加载、glTF 二进制数据处理等。",[18,575,577],{"className":20,"code":576,"language":22,"meta":23,"style":23},"int len;\nunsigned char *data = read_bin_file_alloc(\"image.bmp\", &len);\nif (data) {\n    \u002F\u002F 使用 data...\n    free(data);\n}\n",[25,578,579,584,589,594,599,604],{"__ignoreMap":23},[28,580,581],{"class":30,"line":31},[28,582,583],{},"int len;\n",[28,585,586],{"class":30,"line":108},[28,587,588],{},"unsigned char *data = read_bin_file_alloc(\"image.bmp\", &len);\n",[28,590,591],{"class":30,"line":114},[28,592,593],{},"if (data) {\n",[28,595,596],{"class":30,"line":181},[28,597,598],{},"    \u002F\u002F 使用 data...\n",[28,600,601],{"class":30,"line":188},[28,602,603],{},"    free(data);\n",[28,605,606],{"class":30,"line":194},[28,607,608],{},"}\n",[199,610],{},[14,612,613],{"id":613},"数据库",[35,615,616],{},"eduwin 已内置 SQLite 嵌入式数据库引擎，无需任何额外配置：",[18,618,620],{"className":20,"code":619,"language":22,"meta":23,"style":23},"#include \"eduwin.h\"\n#include \"sqlite3.h\"\n\nsqlite3 *db;\nsqlite3_open(\"test.db\", &db);\nsqlite3_exec(db, \"CREATE TABLE IF NOT EXISTS ...\", NULL, NULL, NULL);\nsqlite3_close(db);\n",[25,621,622,627,632,636,641,646,651],{"__ignoreMap":23},[28,623,624],{"class":30,"line":31},[28,625,626],{},"#include \"eduwin.h\"\n",[28,628,629],{"class":30,"line":108},[28,630,631],{},"#include \"sqlite3.h\"\n",[28,633,634],{"class":30,"line":114},[28,635,185],{"emptyLinePlaceholder":184},[28,637,638],{"class":30,"line":181},[28,639,640],{},"sqlite3 *db;\n",[28,642,643],{"class":30,"line":188},[28,644,645],{},"sqlite3_open(\"test.db\", &db);\n",[28,647,648],{"class":30,"line":194},[28,649,650],{},"sqlite3_exec(db, \"CREATE TABLE IF NOT EXISTS ...\", NULL, NULL, NULL);\n",[28,652,653],{"class":30,"line":431},[28,654,655],{},"sqlite3_close(db);\n",[35,657,658,659,61,664,667],{},"详见 ",[660,661,663],"a",{"href":662},"..\u002Ftutorial\u002Feduwin-sqlite","eduwin-sqlite.md",[25,665,666],{},"samples\\sqlite_demo\\sqlite_demo.c"," 是一个完整的用户信息增删改查演示。",[199,669],{},[14,671,672],{"id":672},"进程管理",[18,674,676],{"className":20,"code":675,"language":22,"meta":23,"style":23},"HANDLE run_process(const WCHAR *exe_path, const WCHAR *cmdline, int show);\nint    kill_process(HANDLE proc);\nint    kill_process_pid(DWORD pid);\nint    wait_process(HANDLE proc);\n",[25,677,678,683,688,693],{"__ignoreMap":23},[28,679,680],{"class":30,"line":31},[28,681,682],{},"HANDLE run_process(const WCHAR *exe_path, const WCHAR *cmdline, int show);\n",[28,684,685],{"class":30,"line":108},[28,686,687],{},"int    kill_process(HANDLE proc);\n",[28,689,690],{"class":30,"line":114},[28,691,692],{},"int    kill_process_pid(DWORD pid);\n",[28,694,695],{"class":30,"line":181},[28,696,697],{},"int    wait_process(HANDLE proc);\n",[35,699,700,703,704,707,708,711,712,151,714,717,718,721,722,61],{},[25,701,702],{},"run_process"," 创建新进程。",[25,705,706],{},"exe_path"," 为可执行文件路径，",[25,709,710],{},"cmdline"," 为命令行参数（可为 ",[25,713,94],{},[25,715,716],{},"show=1"," 显示窗口，",[25,719,720],{},"show=0"," 隐藏窗口。成功返回进程句柄，失败返回 ",[25,723,94],{},[35,725,726,729],{},[25,727,728],{},"kill_process"," 强制终止进程并关闭句柄，成功返回 0。",[35,731,732,735,736,739,740,742],{},[25,733,734],{},"kill_process_pid"," 按进程 PID 终止进程（内部调用 ",[25,737,738],{},"OpenProcess"," + ",[25,741,728],{},"），成功返回 0。",[35,744,745,748],{},[25,746,747],{},"wait_process"," 等待进程结束，返回进程退出码（内部会自动关闭句柄）。",[18,750,752],{"className":20,"code":751,"language":22,"meta":23,"style":23},"\u002F\u002F 启动记事本，等待退出\nHANDLE h = run_process(L\"C:\\\\Windows\\\\System32\\\\notepad.exe\", NULL, 1);\nif (h) {\n    int code = wait_process(h);\n    log_info(L\"记事本已退出\");\n}\n\n\u002F\u002F 后台启动 cmd\nHANDLE h2 = run_process(L\"C:\\\\Windows\\\\System32\\\\cmd.exe\", NULL, 1);\n\u002F\u002F 稍后终止\nkill_process(h2);\n\n\u002F\u002F 按 PID 终止进程\nkill_process_pid(1234);\n",[25,753,754,759,764,769,774,779,783,787,792,797,802,807,811,816],{"__ignoreMap":23},[28,755,756],{"class":30,"line":31},[28,757,758],{},"\u002F\u002F 启动记事本，等待退出\n",[28,760,761],{"class":30,"line":108},[28,762,763],{},"HANDLE h = run_process(L\"C:\\\\Windows\\\\System32\\\\notepad.exe\", NULL, 1);\n",[28,765,766],{"class":30,"line":114},[28,767,768],{},"if (h) {\n",[28,770,771],{"class":30,"line":181},[28,772,773],{},"    int code = wait_process(h);\n",[28,775,776],{"class":30,"line":188},[28,777,778],{},"    log_info(L\"记事本已退出\");\n",[28,780,781],{"class":30,"line":194},[28,782,608],{},[28,784,785],{"class":30,"line":431},[28,786,185],{"emptyLinePlaceholder":184},[28,788,789],{"class":30,"line":437},[28,790,791],{},"\u002F\u002F 后台启动 cmd\n",[28,793,794],{"class":30,"line":443},[28,795,796],{},"HANDLE h2 = run_process(L\"C:\\\\Windows\\\\System32\\\\cmd.exe\", NULL, 1);\n",[28,798,799],{"class":30,"line":449},[28,800,801],{},"\u002F\u002F 稍后终止\n",[28,803,804],{"class":30,"line":455},[28,805,806],{},"kill_process(h2);\n",[28,808,809],{"class":30,"line":461},[28,810,185],{"emptyLinePlaceholder":184},[28,812,813],{"class":30,"line":466},[28,814,815],{},"\u002F\u002F 按 PID 终止进程\n",[28,817,818],{"class":30,"line":472},[28,819,820],{},"kill_process_pid(1234);\n",[14,822,823],{"id":823},"进程枚举",[18,825,827],{"className":20,"code":826,"language":22,"meta":23,"style":23},"typedef struct {\n    DWORD pid;\n    WCHAR name[260];\n} process_entry_t;\n\nint enum_processes(process_entry_t **out, int *count);\n",[25,828,829,833,838,843,848,852],{"__ignoreMap":23},[28,830,831],{"class":30,"line":31},[28,832,404],{},[28,834,835],{"class":30,"line":108},[28,836,837],{},"    DWORD pid;\n",[28,839,840],{"class":30,"line":114},[28,841,842],{},"    WCHAR name[260];\n",[28,844,845],{"class":30,"line":181},[28,846,847],{},"} process_entry_t;\n",[28,849,850],{"class":30,"line":188},[28,851,185],{"emptyLinePlaceholder":184},[28,853,854],{"class":30,"line":194},[28,855,856],{},"int enum_processes(process_entry_t **out, int *count);\n",[35,858,859,862,863,865,866,868,869,871],{},[25,860,861],{},"enum_processes"," 枚举所有系统进程，动态分配数组并通过 ",[25,864,244],{}," 返回。",[25,867,386],{}," 返回进程数量。成功返回 0。调用方需 ",[25,870,567],{}," 释放返回的数组。",[18,873,875],{"className":20,"code":874,"language":22,"meta":23,"style":23},"process_entry_t *procs = NULL;\nint count = 0;\nif (enum_processes(&procs, &count) == 0) {\n    for (int i = 0; i \u003C count; i++)\n        wprintf(L\"%u  %s\\n\", procs[i].pid, procs[i].name);\n    free(procs);\n}\n",[25,876,877,882,887,892,897,902,907],{"__ignoreMap":23},[28,878,879],{"class":30,"line":31},[28,880,881],{},"process_entry_t *procs = NULL;\n",[28,883,884],{"class":30,"line":108},[28,885,886],{},"int count = 0;\n",[28,888,889],{"class":30,"line":114},[28,890,891],{},"if (enum_processes(&procs, &count) == 0) {\n",[28,893,894],{"class":30,"line":181},[28,895,896],{},"    for (int i = 0; i \u003C count; i++)\n",[28,898,899],{"class":30,"line":188},[28,900,901],{},"        wprintf(L\"%u  %s\\n\", procs[i].pid, procs[i].name);\n",[28,903,904],{"class":30,"line":194},[28,905,906],{},"    free(procs);\n",[28,908,909],{"class":30,"line":431},[28,910,608],{},[14,912,913],{"id":913},"系统信息",[18,915,917],{"className":20,"code":916,"language":22,"meta":23,"style":23},"typedef struct {\n    WCHAR computer_name[64];\n    WCHAR user_name[64];\n    WCHAR os_version[64];\n    int   cpu_cores;\n    WCHAR cpu_name[128];\n    unsigned long long mem_total_mb;\n    unsigned long long mem_avail_mb;\n    WCHAR windows_dir[MAX_PATH];\n} sys_info_t;\n\nint get_sys_info(sys_info_t *info);\n",[25,918,919,923,928,933,938,943,948,953,958,963,968,972],{"__ignoreMap":23},[28,920,921],{"class":30,"line":31},[28,922,404],{},[28,924,925],{"class":30,"line":108},[28,926,927],{},"    WCHAR computer_name[64];\n",[28,929,930],{"class":30,"line":114},[28,931,932],{},"    WCHAR user_name[64];\n",[28,934,935],{"class":30,"line":181},[28,936,937],{},"    WCHAR os_version[64];\n",[28,939,940],{"class":30,"line":188},[28,941,942],{},"    int   cpu_cores;\n",[28,944,945],{"class":30,"line":194},[28,946,947],{},"    WCHAR cpu_name[128];\n",[28,949,950],{"class":30,"line":431},[28,951,952],{},"    unsigned long long mem_total_mb;\n",[28,954,955],{"class":30,"line":437},[28,956,957],{},"    unsigned long long mem_avail_mb;\n",[28,959,960],{"class":30,"line":443},[28,961,962],{},"    WCHAR windows_dir[MAX_PATH];\n",[28,964,965],{"class":30,"line":449},[28,966,967],{},"} sys_info_t;\n",[28,969,970],{"class":30,"line":455},[28,971,185],{"emptyLinePlaceholder":184},[28,973,974],{"class":30,"line":461},[28,975,976],{},"int get_sys_info(sys_info_t *info);\n",[35,978,979,982,983,986],{},[25,980,981],{},"get_sys_info"," 填充系统信息到 ",[25,984,985],{},"sys_info_t"," 结构体。成功返回 0。",[18,988,990],{"className":20,"code":989,"language":22,"meta":23,"style":23},"sys_info_t info;\nget_sys_info(&info);\n\u002F\u002F info.computer_name → 计算机名\n\u002F\u002F info.os_version → \"Windows 10 Pro (Build 19045, 22H2)\"\n\u002F\u002F info.cpu_cores → 8\n\u002F\u002F info.cpu_name → \"Intel(R) Core(TM) i7-10700\"\n\u002F\u002F info.mem_total_mb → 16384\n",[25,991,992,997,1002,1007,1012,1017,1022],{"__ignoreMap":23},[28,993,994],{"class":30,"line":31},[28,995,996],{},"sys_info_t info;\n",[28,998,999],{"class":30,"line":108},[28,1000,1001],{},"get_sys_info(&info);\n",[28,1003,1004],{"class":30,"line":114},[28,1005,1006],{},"\u002F\u002F info.computer_name → 计算机名\n",[28,1008,1009],{"class":30,"line":181},[28,1010,1011],{},"\u002F\u002F info.os_version → \"Windows 10 Pro (Build 19045, 22H2)\"\n",[28,1013,1014],{"class":30,"line":188},[28,1015,1016],{},"\u002F\u002F info.cpu_cores → 8\n",[28,1018,1019],{"class":30,"line":194},[28,1020,1021],{},"\u002F\u002F info.cpu_name → \"Intel(R) Core(TM) i7-10700\"\n",[28,1023,1024],{"class":30,"line":431},[28,1025,1026],{},"\u002F\u002F info.mem_total_mb → 16384\n",[14,1028,1029],{"id":1029},"注册表读写",[18,1031,1033],{"className":20,"code":1032,"language":22,"meta":23,"style":23},"int reg_read_str(HKEY root, const WCHAR *key, const WCHAR *value, WCHAR *buf, int size);\nint reg_read_dword(HKEY root, const WCHAR *key, const WCHAR *value, DWORD *out);\nint reg_write_str(HKEY root, const WCHAR *key, const WCHAR *value, const WCHAR *data);\nint reg_write_dword(HKEY root, const WCHAR *key, const WCHAR *value, DWORD data);\nint reg_delete_value(HKEY root, const WCHAR *key, const WCHAR *value);\n",[25,1034,1035,1040,1045,1050,1055],{"__ignoreMap":23},[28,1036,1037],{"class":30,"line":31},[28,1038,1039],{},"int reg_read_str(HKEY root, const WCHAR *key, const WCHAR *value, WCHAR *buf, int size);\n",[28,1041,1042],{"class":30,"line":108},[28,1043,1044],{},"int reg_read_dword(HKEY root, const WCHAR *key, const WCHAR *value, DWORD *out);\n",[28,1046,1047],{"class":30,"line":114},[28,1048,1049],{},"int reg_write_str(HKEY root, const WCHAR *key, const WCHAR *value, const WCHAR *data);\n",[28,1051,1052],{"class":30,"line":181},[28,1053,1054],{},"int reg_write_dword(HKEY root, const WCHAR *key, const WCHAR *value, DWORD data);\n",[28,1056,1057],{"class":30,"line":188},[28,1058,1059],{},"int reg_delete_value(HKEY root, const WCHAR *key, const WCHAR *value);\n",[35,1061,1062,1063,1066,1067,159,1070,1073],{},"注册表读写操作。",[25,1064,1065],{},"root"," 为根键（如 ",[25,1068,1069],{},"HKEY_LOCAL_MACHINE",[25,1071,1072],{},"key"," 为键路径。成功返回 0。写操作会自动创建不存在的键。",[18,1075,1077],{"className":20,"code":1076,"language":22,"meta":23,"style":23},"WCHAR cpu_name[128];\nreg_read_str(HKEY_LOCAL_MACHINE,\n    L\"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n    L\"ProcessorNameString\", cpu_name, 128);\n\nDWORD value = 1;\nreg_write_dword(HKEY_CURRENT_USER,\n    L\"Software\\\\MyApp\", L\"Setting\", value);\n",[25,1078,1079,1084,1089,1094,1099,1103,1108,1113],{"__ignoreMap":23},[28,1080,1081],{"class":30,"line":31},[28,1082,1083],{},"WCHAR cpu_name[128];\n",[28,1085,1086],{"class":30,"line":108},[28,1087,1088],{},"reg_read_str(HKEY_LOCAL_MACHINE,\n",[28,1090,1091],{"class":30,"line":114},[28,1092,1093],{},"    L\"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n",[28,1095,1096],{"class":30,"line":181},[28,1097,1098],{},"    L\"ProcessorNameString\", cpu_name, 128);\n",[28,1100,1101],{"class":30,"line":188},[28,1102,185],{"emptyLinePlaceholder":184},[28,1104,1105],{"class":30,"line":194},[28,1106,1107],{},"DWORD value = 1;\n",[28,1109,1110],{"class":30,"line":431},[28,1111,1112],{},"reg_write_dword(HKEY_CURRENT_USER,\n",[28,1114,1115],{"class":30,"line":437},[28,1116,1117],{},"    L\"Software\\\\MyApp\", L\"Setting\", value);\n",[14,1119,1120],{"id":1120},"环境变量",[18,1122,1124],{"className":20,"code":1123,"language":22,"meta":23,"style":23},"int get_env(const WCHAR *name, WCHAR *buf, int size);\nint set_env(const WCHAR *name, const WCHAR *value);\n",[25,1125,1126,1131],{"__ignoreMap":23},[28,1127,1128],{"class":30,"line":31},[28,1129,1130],{},"int get_env(const WCHAR *name, WCHAR *buf, int size);\n",[28,1132,1133],{"class":30,"line":108},[28,1134,1135],{},"int set_env(const WCHAR *name, const WCHAR *value);\n",[35,1137,1138,1141,1142,1145],{},[25,1139,1140],{},"get_env"," 读取环境变量，成功返回 0。",[25,1143,1144],{},"set_env"," 设置环境变量（仅影响当前进程），成功返回 0。",[18,1147,1149],{"className":20,"code":1148,"language":22,"meta":23,"style":23},"WCHAR path_val[4096];\nget_env(L\"PATH\", path_val, 4096);\n\nset_env(L\"MY_VAR\", L\"hello\");\n",[25,1150,1151,1156,1161,1165],{"__ignoreMap":23},[28,1152,1153],{"class":30,"line":31},[28,1154,1155],{},"WCHAR path_val[4096];\n",[28,1157,1158],{"class":30,"line":108},[28,1159,1160],{},"get_env(L\"PATH\", path_val, 4096);\n",[28,1162,1163],{"class":30,"line":114},[28,1164,185],{"emptyLinePlaceholder":184},[28,1166,1167],{"class":30,"line":181},[28,1168,1169],{},"set_env(L\"MY_VAR\", L\"hello\");\n",[14,1171,1172],{"id":1172},"特殊文件夹",[18,1174,1176],{"className":20,"code":1175,"language":22,"meta":23,"style":23},"#define FOLDER_DESKTOP      0\n#define FOLDER_DOCUMENTS    1\n#define FOLDER_DOWNLOADS    2\n#define FOLDER_PICTURES     3\n#define FOLDER_MUSIC        4\n#define FOLDER_VIDEOS       5\n#define FOLDER_APPDATA      6\n#define FOLDER_LOCALAPPDATA 7\n#define FOLDER_PROGRAMFILES 8\n#define FOLDER_STARTUP      9\n\nint get_special_folder(int folder_id, WCHAR *buf, int size);\n",[25,1177,1178,1183,1188,1193,1198,1203,1208,1213,1218,1223,1228,1232],{"__ignoreMap":23},[28,1179,1180],{"class":30,"line":31},[28,1181,1182],{},"#define FOLDER_DESKTOP      0\n",[28,1184,1185],{"class":30,"line":108},[28,1186,1187],{},"#define FOLDER_DOCUMENTS    1\n",[28,1189,1190],{"class":30,"line":114},[28,1191,1192],{},"#define FOLDER_DOWNLOADS    2\n",[28,1194,1195],{"class":30,"line":181},[28,1196,1197],{},"#define FOLDER_PICTURES     3\n",[28,1199,1200],{"class":30,"line":188},[28,1201,1202],{},"#define FOLDER_MUSIC        4\n",[28,1204,1205],{"class":30,"line":194},[28,1206,1207],{},"#define FOLDER_VIDEOS       5\n",[28,1209,1210],{"class":30,"line":431},[28,1211,1212],{},"#define FOLDER_APPDATA      6\n",[28,1214,1215],{"class":30,"line":437},[28,1216,1217],{},"#define FOLDER_LOCALAPPDATA 7\n",[28,1219,1220],{"class":30,"line":443},[28,1221,1222],{},"#define FOLDER_PROGRAMFILES 8\n",[28,1224,1225],{"class":30,"line":449},[28,1226,1227],{},"#define FOLDER_STARTUP      9\n",[28,1229,1230],{"class":30,"line":455},[28,1231,185],{"emptyLinePlaceholder":184},[28,1233,1234],{"class":30,"line":461},[28,1235,1236],{},"int get_special_folder(int folder_id, WCHAR *buf, int size);\n",[35,1238,1239,1242],{},[25,1240,1241],{},"get_special_folder"," 获取系统特殊文件夹路径。成功返回 0。",[18,1244,1246],{"className":20,"code":1245,"language":22,"meta":23,"style":23},"WCHAR path[MAX_PATH];\nget_special_folder(FOLDER_DOWNLOADS, path, MAX_PATH);\n\u002F\u002F path → \"C:\\Users\\xxx\\Downloads\"\n",[25,1247,1248,1253,1258],{"__ignoreMap":23},[28,1249,1250],{"class":30,"line":31},[28,1251,1252],{},"WCHAR path[MAX_PATH];\n",[28,1254,1255],{"class":30,"line":108},[28,1256,1257],{},"get_special_folder(FOLDER_DOWNLOADS, path, MAX_PATH);\n",[28,1259,1260],{"class":30,"line":114},[28,1261,1262],{},"\u002F\u002F path → \"C:\\Users\\xxx\\Downloads\"\n",[14,1264,1265],{"id":1265},"日志",[18,1267,1269],{"className":20,"code":1268,"language":22,"meta":23,"style":23},"void log_info(const WCHAR *text);\nvoid log_warning(const WCHAR *text);\nvoid log_error(const WCHAR *title);\nvoid log_clear(void);\n",[25,1270,1271,1276,1281,1286],{"__ignoreMap":23},[28,1272,1273],{"class":30,"line":31},[28,1274,1275],{},"void log_info(const WCHAR *text);\n",[28,1277,1278],{"class":30,"line":108},[28,1279,1280],{},"void log_warning(const WCHAR *text);\n",[28,1282,1283],{"class":30,"line":114},[28,1284,1285],{},"void log_error(const WCHAR *title);\n",[28,1287,1288],{"class":30,"line":181},[28,1289,1290],{},"void log_clear(void);\n",[35,1292,1293,1294,1297,1298,1301,1302,1301,1305,1308],{},"将文本写入 exe 所在目录下的 ",[25,1295,1296],{},"log.txt"," 文件，自动在行首添加日期时间戳（精确到毫秒）和标签（",[25,1299,1300],{},"[INFO]"," \u002F ",[25,1303,1304],{},"[WARN]",[25,1306,1307],{},"[ERROR]","）。日志以追加方式写入。",[35,1310,1311,1314,1315,1317,1318,1321],{},[25,1312,1313],{},"log_error"," 除了写入时间戳和 ",[25,1316,1307],{}," 标签外，还会自动追加 ",[25,1319,1320],{},"GetLastError()"," 的错误码和对应的系统错误描述。",[35,1323,1324,1327],{},[25,1325,1326],{},"log_clear"," 清空日志文件。",[18,1329,1331],{"className":20,"code":1330,"language":22,"meta":23,"style":23},"log_info(L\"程序启动完成\");\nlog_warning(L\"纹理加载失败，使用默认纹理\");\nlog_error(L\"CreateDevice\");  \u002F\u002F 自动追加 err=87 - 参数错误\nlog_clear();\n",[25,1332,1333,1338,1343,1348],{"__ignoreMap":23},[28,1334,1335],{"class":30,"line":31},[28,1336,1337],{},"log_info(L\"程序启动完成\");\n",[28,1339,1340],{"class":30,"line":108},[28,1341,1342],{},"log_warning(L\"纹理加载失败，使用默认纹理\");\n",[28,1344,1345],{"class":30,"line":114},[28,1346,1347],{},"log_error(L\"CreateDevice\");  \u002F\u002F 自动追加 err=87 - 参数错误\n",[28,1349,1350],{"class":30,"line":181},[28,1351,1352],{},"log_clear();\n",[35,1354,1355],{},"输出示例：",[18,1357,1362],{"className":1358,"code":1360,"language":1361},[1359],"language-text","2026-06-23 14:30:01.123 [INFO] 程序启动完成\n2026-06-23 14:30:02.456 [WARN] 纹理加载失败，使用默认纹理\n2026-06-23 14:30:03.789 [ERROR] CreateDevice (err=87 - 参数错误)\n","text",[25,1363,1360],{"__ignoreMap":23},[1365,1366,1367],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":23,"searchDepth":108,"depth":108,"links":1369},[1370,1371,1372,1373,1378,1379,1380,1381,1382,1383,1384,1385],{"id":16,"depth":108,"text":16},{"id":203,"depth":108,"text":203},{"id":220,"depth":108,"text":221},{"id":275,"depth":108,"text":275,"children":1374},[1375,1376,1377],{"id":279,"depth":114,"text":279},{"id":346,"depth":114,"text":346},{"id":543,"depth":114,"text":544},{"id":613,"depth":108,"text":613},{"id":672,"depth":108,"text":672},{"id":823,"depth":108,"text":823},{"id":913,"depth":108,"text":913},{"id":1029,"depth":108,"text":1029},{"id":1120,"depth":108,"text":1120},{"id":1172,"depth":108,"text":1172},{"id":1265,"depth":108,"text":1265},"md",{},"\u002Fdocs\u002Fapi\u002Feduwin-util-api",{"title":5,"description":23},"docs\u002Fapi\u002Feduwin-util-api","QdGasvXE2cGMTs9c51NnjfIYExWNNySthJCWyZtmKig",1782488679848]