Python与C - 在Windows中处理环境变量

2 投票
3 回答
1151 浏览
提问于 2025-04-15 15:05

我发现,在Windows系统中,C语言和Python代码的输出结果有些不同,虽然它们想实现相同的功能。C语言的代码(类似于Unix的脚本)在'test.bat.output'文件中显示了TEST1这个环境变量,但它的值是空字符串。而Python的代码则把这个环境变量给删掉了。

有没有办法让Python在环境变量为空的时候,不把它从环境表中删除呢?

C

#include <windows.h>

main()
{

  DWORD dwRet;
  char pszOldVal[1024] = "abc";

  if(! SetEnvironmentVariable("TEST1", ""))  
    puts("Error\n");

  // _putenv("TEST1=");

  // GetEnvironmentVariable("TEST1", pszOldVal, dwRet);
  system("cmd /c test.bat >test.bat.output");
}

Python

import os
os.environ['TEST1'] = ""
os.environ['TEST2'] = "karthik"
os.system("cmd /c test.bat > test.bat.output.python")

-Karthik

3 个回答

0

是的,空值不会被放入环境变量中。不过有趣的是,从win32api或ctypes模块调用SetEnvironmentVariable的效果和os.environ是一样的,尽管win32api.SetEnvironmentVariable实际上调用的是和C语言中相同的函数。

那么,你确定在C代码中得到的结果是不同的吗?

import win32api
import os
win32api.SetEnvironmentVariable("TEST1", "")
# or 
# import ctypes
# ctypes.windll.kernel32.SetEnvironmentVariable("TEST1", "")
os.system("echo %TEST1%")
2

在Windows和其他大多数操作系统(那些源自或受到Unix启发的系统)之间,想要实现跨平台兼容性常常很困难,尤其是在那些不可避免的小问题上(比如这个问题:“把环境变量设置为空,是否意味着取消设置?”)。有时候,直接使用Windows特有的功能会比试图让“跨平台”功能适应更简单。

传统上,从Python访问Windows特有功能的方式是使用win32all扩展包,但在最近的Python版本中,ctypes这个标准库模块提供了一个替代方案,它的好处是无需安装C语言编写的扩展。一个有趣的项目是jaraco.windows,这是一个基于ctypes的纯Python代码集合,旨在让Windows操作变得更简单、更顺畅。例如,如果你需要处理环境变量或注册表,environ.py模块提供了一组功能和类,它们比直接使用底层ctypes访问的win32 API更符合Python的风格(比如在出错时能得到可读的错误信息,而不是只检查返回码等)。

0

这是一个可能的回答。我手头没有Windows系统可以测试,所以我不太清楚这段代码会有什么效果,但如果你这样做,会发生什么呢:

import os, subprocess
myenv = {}
myenv.update(os.environ)
myenv['TEST1'] = ""
myenv['TEST2'] = "karthik"
subprocess.Popen(('cmd', '/c', 'test.bat'), stdout=file("test.bat.output.python", 'w'),
                 env=myenv).wait()

在我看来,你可能遇到了某种Python的bug。特别是如果我刚给你的代码能够正常工作的话。

另外,在Unix系统下测试你的代码是可以的。最终的环境变量会是一个空的状态。

撰写回答