找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 323|回复: 22

wapi 调用win32 api

[复制链接]
发表于 6 天前 | 显示全部楼层 |阅读模式
本帖最后由 went 于 2026-11-13 23:20 编辑

可以调用一些简单的api,测试脚本放在1楼

  1. win32 api 调用

  2. wapi.exe 用法:

  3.   初始化         wapi -init [-debug]

  4.   释放资源       wapi -free

  5.   设置同步模式   wapi -sync,async

  6.   设置变量       wapi -set name { #num[b,o,h] |  @float | $var | str }

  7.   获取变量       wapi -get name [-str | -int | -float]

  8.   显示所有变量   wapi -show

  9.   显示变量内存   wapi -mshow name size [-offset 0] [-r radix] [-addr]

  10.   设置变量内存   wapi -mset name value [-offset 0] [-s,b,w,d,q] [-addr]

  11.   获取变量内存   wapi -mget name {-b,w,d,q,s} [-offset 0] [-addr]

  12.   填充变量内存   wapi -mfill name count value [-offset 0] [-s,b,w,d,q] [-addr]

  13.   调用API        wapi -call mod fun [args ...]

  14.   调用API并返回  wapi -rcall ret mod fun [args ...]

  15.   查看示例       wapi -sample

  16.   备注:
  17.       1.首次调用init初始化,后面调用清空所有变量,init和free请配套使用

  18.       2.$var表示变量的值,$$var表示取变量的地址,在call时可用

  19.       3.内置变量 $WAPI_FUN_0 ~ $WAPI_FUN_5,分别为有0~5个参数的回调函数,在call时可用

  20.       4.要操作float或int变量内存,请在mshow,mget,mset,mfill命令添加-addr开关

复制代码

这个是下载地址 https://gitee.com/wentlis/wapi/releases

评分

参与人数 1技术 +1 收起 理由
cutebe + 1 厉害!

查看全部评分

 楼主| 发表于 6 天前 | 显示全部楼层
本帖最后由 went 于 2026-11-13 22:17 编辑

示例 - 简单调用.bat
  1. @echo off & cd /d "%~dp0"

  2. rem wapi测试脚本

  3. wapi -init

  4. rem 对话框
  5. call :msgbox

  6. rem 获取控制台窗口文字
  7. call :get_title

  8. rem 设置控制台窗口文字
  9. call :set_title

  10. wapi -free

  11. pause&exit

  12. :msgbox
  13. wapi -call user32 MessageBoxA #0 "内容" "标题" #4
  14. goto :eof

  15. :get_title
  16. title 这是测试标题
  17. wapi -rcall hHeap kernel32 GetProcessHeap
  18. wapi -rcall lpMem kernel32 HeapAlloc $hHeap #0 #1024
  19. wapi -rcall hwnd  kernel32 GetConsoleWindow
  20. wapi -rcall len   user32   GetWindowTextA $hwnd $lpMem #1024
  21. wapi -get lpMem -str
  22. wapi -call kernel32 HeapFree $hHeap #0 $lpMem
  23. goto :eof

  24. :set_title
  25. wapi -rcall hwnd  kernel32 GetConsoleWindow
  26. wapi -call user32 SetWindowTextA $hwnd "这是设置的标题"
  27. goto :eof
复制代码
发表于 5 天前 | 显示全部楼层
本帖最后由 87zrjojo 于 2026-11-10 09:37 编辑

感觉好高级。但怎么用,有没有更详细一说明?比如像MessageBoxA这样的模块是在哪里找到的,怎么用它的参数。能不能实现在win7以上系统中用命令行安装字体?因为直接复制字体到Fonts目录不能生效。感觉用你这个工具好像有可能解决。
发表于 5 天前 | 显示全部楼层
本帖最后由 cutebe 于 2026-11-12 08:20 编辑
87zrjojo 发表于 2026-11-10 09:33
感觉好高级。但怎么用,有没有更详细一说明?比如像MessageBoxA这样的模块是在哪里找到的,怎么用它的参数 ...


加载字体,试试WinAPI:AddFontResource
测试字体可以仅用WinAPI,不复制也添加注册表。
发重启后字体仍可用,则加注册表。
  1. ::WAPI安装字体 拖入字体文件
  2. ::@echo off
  3. if "%~1"=="" echo 请拖入字体文件(.ttf/.otf)……&pause&goto :eof

  4. set "字体文件=%~1" %_字体_ttf_otf_%
  5. set "安装路径=C:\Windows\Fonts"
  6. call :安装字体 "%字体文件%" "%安装路径%"
  7. echo 安装完成。

  8. pause
  9. goto :eof
  10. ::结束

  11. :安装字体
  12. setLocal
  13. set "字体文件=%~1"
  14. set "字体名=%~n1"
  15. set "字体文件名=%~nx1"
  16. if "%~2"=="" (set "安装路径=%~dp1")else set "安装路径=%~2"
  17. if "%安装路径:~-1%"=="\" set "安装路径=%安装路径:~,-1%"
  18. ::复制与注册表,使重启有效
  19. copy/b/y "%字体文件%" "%安装路径%"
  20. reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "%字体名%" /d "%字体文件名%" /f

  21. wapi -init %_初始化wapi_%
  22. ::加载字体
  23. wapi -call gdi32 AddFontResourceA "%安装路径%\%字体文件名%"
  24. ::通知窗口,使当前有效
  25. ::wapi -call user32 SendMessageA #65535 #29 #0 #0
  26. ::能否直接支持16进制数0xF
  27. ::wapi -call user32 SendMessageA #0xFFFF #0x001D #0 #0
  28. wapi -free %_释放wapi_%
  29. endLocal
  30. goto :eof
复制代码
发表于 5 天前 | 显示全部楼层
cutebe 发表于 2026-11-10 15:17
加载字体,试试WinAPI:AddFontResource

有没有具体点的操作步骤方法,实在不太懂该怎么传递或传递哪些参数
发表于 5 天前 | 显示全部楼层
建议加上声明, 声明不要用此程序来调用winpai dll之外的其他dll, 其他dll的调用约定可能不同
int是dword, str不支持转义吧, 没有byte方式的读取和写入, 不方便用HeapAlloc分配的内存来呈现结构
还有吐槽下winapi很难用, 是真的难用, 各种的例外与限制, 不能一步到位真的呛, 像是一个WriteConsoleW, 第三个参数内部明明会进行计算对比却不给你自动, 非得先计算一次, 而且不支持重定向, 想要WriteConsoleW不出问题, 实际上还得多调用4个左右的其他api
 楼主| 发表于 4 天前 | 显示全部楼层
本帖最后由 went 于 2026-11-11 00:16 编辑
Five66 发表于 2026-11-10 23:56
建议加上声明, 声明不要用此程序来调用winpai dll之外的其他dll, 其他dll的调用约定可能不同
int是dword, s ...


c的dll没有测试,应该会闪退.二进制编辑后面会加入更新
 楼主| 发表于 4 天前 | 显示全部楼层
本帖最后由 went 于 2026-11-13 22:49 编辑

1.1版更新了用管道输出,效率会更慢,但可以被for /f捕获输出
添加了内置的回调函数 $WAPI_FUN_0 ~ $WAPI_FUN_5,使用如下:
  1. @echo off & cd /d "%~dp0"
  2. rem 遍历窗口句柄并获取窗口标题
  3. wapi -init
  4. wapi -async
  5. wapi -rcall hHeap kernel32 GetProcessHeap
  6. wapi -rcall lpMem kernel32 HeapAlloc $hHeap #0 #1024
  7. for /f "tokens=1,2" %%i in ('wapi -call user32 EnumWindows $WAPI_FUN_2 #123') do (
  8.         wapi -rcall len user32 GetWindowTextA #%%i $lpMem #1024
  9.         set "title="
  10.         for /f "delims=" %%a in ('wapi -get lpMem -str') do set "title=%%a"
  11.         call echo 窗口句柄:%%i 窗口标题:%%title%%
  12. )
  13. wapi -free

  14. pause&exit
复制代码

评分

参与人数 1技术 +1 收起 理由
cutebe + 1 有意义的更新

查看全部评分

发表于 3 天前 | 显示全部楼层
87zrjojo 发表于 2026-11-10 16:51
有没有具体点的操作步骤方法,实在不太懂该怎么传递或传递哪些参数

更新在4楼
发表于 3 天前 | 显示全部楼层
went 发表于 2026-11-11 00:08
1.1版更新了用管道输出,效率会更慢,但可以被for /f捕获输出
添加了内置的回调函数 $WAPI_FUN_0 ~ $WAPI_FUN ...

数值能直接支持16进制吗?这样0xFAE7之类的就不用转换了
 楼主| 发表于 3 天前 | 显示全部楼层
本帖最后由 went 于 2026-11-12 22:38 编辑
cutebe 发表于 2026-11-12 08:23
数值能直接支持16进制吗?这样0xFAE7之类的就不用转换了


更新了,可以输入#fa7eh表示
后缀 b,o,h分别表示 2进制,8进制,16进制数字

评分

参与人数 1技术 +1 收起 理由
cutebe + 1 好哇。

查看全部评分

 楼主| 发表于 3 天前 | 显示全部楼层
Five66 发表于 2026-11-10 23:56
建议加上声明, 声明不要用此程序来调用winpai dll之外的其他dll, 其他dll的调用约定可能不同
int是dword, s ...

1.1版更新了内存编辑功能 wapi -sample有详细用法
 楼主| 发表于 前天 22:13 | 显示全部楼层
示例 - 遍历进程.bat 建议管理员权限运行
  1. @echo off & cd /d "%~dp0"
  2. setlocal enabledelayedexpansion
  3. set "PATH=%PATH%;.."

  4. rem 遍历进程

  5. rem 初始化
  6. wapi -init >nul

  7. rem 枚举所有进程id
  8. wapi -rcall hHeap kernel32 GetProcessHeap || goto :err
  9. wapi -rcall lpMem1 kernel32 HeapAlloc $hHeap #8h #4096 || goto :err
  10. wapi -rcall lpMem2 kernel32 HeapAlloc $hHeap #8h #1024 || goto :err
  11. wapi -set n1 #0
  12. wapi -call Psapi EnumProcesses $lpMem1 #4096 $$n1 || goto :err

  13. rem 循环每个进程
  14. set "count=0"
  15. for /f "delims=" %%i in ('wapi -get n1 -int') do set /a "count=%%i/4"
  16. echo 进程总数: %count%
  17. echo ----------
  18. for /l %%i in (1,1,%count%) do (
  19.         set /a "offset=0,id=0"
  20.         rem 计算lpMem中进程id的偏移
  21.         set /a "offset=(%%i-1)*4"
  22.         rem 取出进程id,取1个dword(4字节)
  23.         for /f "delims=" %%a in ('wapi -mget lpMem1 -offset !offset! -d') do set "id=%%a"
  24.         echo 进程id: !id!
  25.         rem 打开进程
  26.         wapi -rcall hProc kernel32 OpenProcess #1000h #0 #!id!
  27.         rem 初始化缓冲区
  28.         wapi -mfill lpMem2 1024 0 -b
  29.         rem 获取进程文件
  30.         wapi -rcall len Psapi GetProcessImageFileNameA $hProc $lpMem2 #1024
  31.         rem 打印
  32.         wapi -get lpMem2 -str
  33.         echo ----------------------
  34. )

  35. wapi -free >nul

  36. pause&exit

  37. :err
  38. echo 调用失败
  39. pause&exit
复制代码
 楼主| 发表于 前天 22:18 | 显示全部楼层
示例 - 桌面绘制小圆.bat
  1. @echo off & cd /d "%~dp0"
  2. set "PATH=%PATH%;.."

  3. rem 桌面绘制小圆

  4. rem 初始化
  5. wapi -init >nul || ( echo 初始化失败 & pause&exit )
  6. wapi -sync

  7. rem 获取屏幕尺寸
  8. for /f "delims=" %%i in ('wapi -call user32 GetSystemMetrics #0') do set "sx=%%i"
  9. for /f "delims=" %%i in ('wapi -call user32 GetSystemMetrics #1') do set "sy=%%i"
  10. echo 屏幕尺寸: %sx%x%sy%

  11. rem 初始化dc和画刷
  12. wapi -rcall hwnd user32 GetDesktopWindow
  13. wapi -rcall hdc user32 GetDC $hwnd
  14. rem 红色实心画刷(#00BBGGRR)
  15. wapi -rcall hbrush gdi32 CreateSolidBrush #ffh
  16. wapi -rcall ret gdi32 SelectObject $hdc $hbrush

  17. rem 在屏幕4个角绘制4个半径为r小圆
  18. set r=50
  19. set /a "left=0,top=0,right=r,bottom=r"
  20. wapi -call gdi32 Ellipse $hdc #%left% #%top% #%right% #%bottom%
  21. set /a "left=sx-r,top=0,right=sx,bottom=r"
  22. wapi -call gdi32 Ellipse $hdc #%left% #%top% #%right% #%bottom%
  23. set /a "left=0,top=sy-r,right=r,bottom=sy"
  24. wapi -call gdi32 Ellipse $hdc #%left% #%top% #%right% #%bottom%
  25. set /a "left=sx-r,top=sy-r,right=sx,bottom=sy"
  26. wapi -call gdi32 Ellipse $hdc #%left% #%top% #%right% #%bottom%

  27. rem 释放dc
  28. wapi -rcall ret user32 ReleaseDC $hwnd $hdc

  29. rem 显示变量
  30. wapi -show

  31. rem 释放资源
  32. wapi -free >nul

  33. pause&exit
复制代码
 楼主| 发表于 前天 22:29 | 显示全部楼层
示例 - 获取时间.bat
  1. @echo off & cd /d "%~dp0"
  2. set "PATH=%PATH%;.."

  3. rem 获取系统时间
  4. rem https://learn.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlocaltime
  5. rem https://learn.microsoft.com/zh-cn/windows/win32/api/minwinbase/ns-minwinbase-systemtime

  6. rem 初始化
  7. wapi -init >nul

  8. rem 申请内存
  9. wapi -rcall hHeap kernel32 GetProcessHeap || goto :err
  10. wapi -rcall lpMem1 kernel32 HeapAlloc $hHeap #8h #16 || goto :err

  11. rem 获取本地时间
  12. wapi -call kernel32 GetLocalTime $lpMem1

  13. rem 取出成员
  14. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 0') do set "year=%%i"
  15. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 2') do set "month=%%i"
  16. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 4') do set "week=%%i"
  17. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 6') do set "day=%%i"
  18. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 8') do set "hour=%%i"
  19. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 10') do set "min=%%i"
  20. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 12') do set "sec=%%i"
  21. for /f "delims=" %%i in ('wapi -mget lpMem1 -w -offset 14') do set "msec=%%i"

  22. echo %year%年%month%月%day%日 %hour%:%min%:%sec%.%msec% 周%week%

  23. wapi -free >nul

  24. pause&exit

  25. :err
  26. echo 调用失败
  27. pause&exit
复制代码

评分

参与人数 1技术 +1 收起 理由
cutebe + 1 如果wapi能直接输出cmd变量就不用那么多for ...

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-11-15 07:19

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表