2

所以我有这个超级脚本,它不断检查程序的系统路径(openvpn)。当您安装 openvpn 时,它会将自身添加到系统路径中。我在控制台中运行我的脚本,在它运行和检查时,我安装了 openvpn。在那个控制台中,我的脚本永远不会在 sys 路径中找到 openvpn。如果我打开一个新控制台并运行相同的脚本,它会找到它。

知道如何使我的脚本不那么愚蠢吗?

import os
import time
import subprocess

def cmd( command ):
    return subprocess.check_output( command, shell = True ) 

def program_in_path( program ):
    path = cmd( "path" ).split(";")
    for p in path:
        if "openvpn" in p.lower():
            return True
    return False


if __name__ == '__main__':
    while True:
        print program_in_path("openvpn")
        time.sleep( 2 )

我认为它来自事物,但如果不使用or shell = True,我还能如何找到它?我得到了没有 sehll 的运行pathWHERE openvpn /QWindowsError: [Error 2] The system cannot find the file specified

下面是用 ruby​​ 完成的程序,它 100% 运行:

loop do
    puts system( "WHERE openvpn /Q" )
    sleep( 5 )
end

不幸的是,我的项目对 python 太深了,现在无法切换语言。太糟糕了。

4

2 回答 2

1

这实际上是因为当你的程序启动时,它已经配置了一个环境。该环境的一部分是系统路径。当您启动子shell 时,它会继承父进程的环境。

我不是 Windows 程序员,而且我现在没有可用于测试的 Windows 机器。但是根据那个错误报告,如果你import nt在你的脚本和reload(nt)你的while True循环中,它会从系统中拉下一个新的环境副本。我不知道这是不是真的。可能值得一试。

对于它的价值,您可以在 cmd 窗口中看到相同的行为,例如,打开命令窗口,将程序文件夹添加到系统路径,然后尝试从现有 cmd 窗口中的该程序文件夹运行 exe . 它不起作用——但打开一个新的 cmd 窗口,它会起作用。

您引用的错误报告是关于另一个问题的。那里概述的问题是,从 Python 内部,如果您加载其中一个系统 DLL 并使用 Windows 提供的特定功能来操作您的环境,Python 不会反映这种变化。但是,如果您对 os.environ 进行更改,Python 会识别该更改。社区的结论是,记者使用的特定功能不是用于获得预期结果的正确功能。

于 2013-05-16T03:37:45.933 回答
1

也许这种方法对您有用,直接从注册表中获取 PATH 变量(因为您在 Windows 上)。

例如,您可以执行以下操作:

import winreg

def PathFromReg():
    loc = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
    reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
    key = winreg.OpenKey(reg, loc)
    n_val = winreg.QueryInfoKey(key)[1]
    for i in range(n_val):
        val = winreg.EnumValue(key, i)
        if val[0] == 'Path':
                return val[1]

path = PathFromReg()                
print('openvpn' in path.lower())

我认为您只需要分配一次密钥,然后查询循环内的值。

注意:在 Python 2 中,该模块被称为_winreg.

于 2013-05-17T15:07:48.700 回答