今天跟大家聊聊我最近折腾的一个小玩意儿:`ExpandEnvironmentStrings`。一开始我看到这个东西的时候,心里是有点懵的,这玩意儿是干啥的?后来一顿操作猛如虎,才算是搞明白。
事情是这样的,最近在搞一个脚本,需要在不同的环境下跑,不同的环境有些参数不一样,我就想着能不能搞个通用的配置,然后根据环境变量来自动替换。一开始想自己写个函数来处理,后来一查资料,发现 Windows API 早就提供 `ExpandEnvironmentStrings` 这个函数,专门干这事的。
第一步:先解这玩意儿是 MSDN 上扒拉半天,看下它的定义,大概意思就是把一个字符串里的环境变量替换成实际的值。比如说,字符串里有 `%TEMP%`,它就会被替换成当前用户的临时目录。听起来是不是挺简单的?
第二步:开始上手。既然知道有这个函数,那就开始用呗。我用的是 Python,所以需要用 `ctypes` 来调用 Windows API。
先 `import ctypes`,然后加载 `*`。
python
kernel32 = *32
第三步:定义函数的参数和返回值。 `ExpandEnvironmentStrings` 函数需要一个输入字符串和一个输出缓冲区,以及缓冲区的大小。返回值是替换后的字符串的长度。
python
ExpandEnvironmentStrings = *
* = (*, *, *)
* = *
第四步:写个简单的测试。 我先写个简单的 Python 脚本来测试一下:
python
import ctypes
import *
kernel32 = *32
ExpandEnvironmentStrings = *
* = (*, *, *)
* = *
def expand_environment_strings(src):
n = ExpandEnvironmentStrings(src, None, 0)
if n == 0:
raise *()
buf = *_unicode_buffer(n)
n = ExpandEnvironmentStrings(src, buf, n)
if n == 0:
raise *()
return *
# 测试
src = "%TEMP%\\*"
expanded_string = expand_environment_strings(src)
print(f"原始字符串: {src}")
print(f"替换后字符串: {expanded_string}")
第五步:运行脚本,看看效果。 结果还不错,`%TEMP%` 成功被替换成我的临时目录。看起来好像没啥问题。
第六步:遇到坑。 本以为一切顺利,结果在实际使用的时候,发现有些环境变量替换不。 仔细一查,原来是有些环境变量是系统级别的,有些是用户级别的。而 `ExpandEnvironmentStrings` 默认只能替换用户级别的环境变量。
第七步:解决问题。 既然知道问题所在,那就想办法解决呗。 查下资料,发现可以用 `GetEnvironmentVariable` 函数来获取系统级别的环境变量,然后自己手动替换。
python
GetEnvironmentVariable = *
* = (*, *, *)
* = *
def get_environment_variable(name):
n = GetEnvironmentVariable(name, None, 0)
if n == 0:
return None # 环境变量不存在
buf = *_unicode_buffer(n)
n = GetEnvironmentVariable(name, buf, n)
if n == 0:
raise *()
return *
def expand_environment_strings_with_system(src):
import re
# 先用 ExpandEnvironmentStrings 替换用户环境变量
expanded = expand_environment_strings(src)
# 再用 GetEnvironmentVariable 替换系统环境变量
for match in *(r"%([A-Za-z0-9_]+)%", expanded):
var_name = *(1)
var_value = get_environment_variable(var_name)
if var_value:
expanded = *(*(0), var_value)
return expanded
- 先用 `expand_environment_strings` 替换用户级别的环境变量。
- 然后用正则表达式找到字符串中所有 `%XXX%` 格式的字符串。
- 对于每一个匹配到的字符串,用 `GetEnvironmentVariable` 函数获取对应的环境变量的值。
- 如果找到环境变量的值,就用这个值替换原始字符串中的 `%XXX%`。
第八步:再次测试。 重新运行脚本,这下所有的环境变量都能正确替换。 搞定!
通过这回实践,我对 Windows API 的调用有更深的解。
`ExpandEnvironmentStrings` 函数虽然简单,但是功能很实用。
遇到问题,还是要多查资料,多尝试,才能找到解决方案。
以后再遇到类似的需求,就可以直接拿来用,省时省力。
这只是一个简单的例子,实际使用中可能还会遇到各种各样的问题,需要根据具体情况进行调整。 希望我的这回实践记录对大家有所帮助。