python - 转换 POSIX->WIN 路径,在 Cygwin Python 中,不调用 cygpath

标签 python cygwin

我使用在 Python 的 Cygwin 构建中运行的 Python 脚本来创建向 native Windows 实用程序(非 Cygwin 感知)发出的命令。这需要在发出命令之前将路径参数从 POSIX 格式转换为 WIN 格式。

调用 cygpath 实用程序是执行此操作的最佳方法,因为它使用 Cygwin 来执行它在那里执行的操作,但它也有点令人恐惧(而且速度很慢)。

我已经在运行 Python 的 Cygwin 构建 - 因此存在进行转换的代码。似乎应该有一个 Cygwin/Python 特定的扩展,让我可以直接在 Python 中使用这个功能,而不必启动一个全新的进程。

最佳答案

这可以通过使用 ctypes 调用 Cygwin API 来实现。下面的代码适用于我——我在 Windows 2012 上使用 64 位 cygwin DLL 版本 2.5.2,这适用于 Python 2.7.10 和 Python 3.4.3 的 Cygwin 版本。

基本上我们称cygwin_create_pathcygwin1.dll 执行路径转换。该函数分配一个包含转换路径的内存缓冲区(使用 malloc)。因此,我们需要使用 cygwin1.dll 中的 free 来释放它分配的缓冲区。

请注意,下面的 xunicodesix 的穷人替代品。 (Python 2/3 兼容库);如果您需要同时支持 Python 2 和 3,那么 6 个是更好的答案,但我希望我的示例不依赖于任何非捆绑模块,这就是我这样做的原因。

from ctypes import cdll, c_void_p, c_int32, cast, c_char_p, c_wchar_p
from sys import version_info

xunicode = str if version_info[0] > 2 else eval("unicode")

# If running under Cygwin Python, just use DLL name
# If running under non-Cygwin Windows Python, use full path to cygwin1.dll
# Note Python and cygwin1.dll must match bitness (i.e. 32-bit Python must
# use 32-bit cygwin1.dll, 64-bit Python must use 64-bit cygwin1.dll.)
cygwin = cdll.LoadLibrary("cygwin1.dll")
cygwin_create_path = cygwin.cygwin_create_path
cygwin_create_path.restype = c_void_p
cygwin_create_path.argtypes = [c_int32, c_void_p]

# Initialise the cygwin DLL. This step should only be done if using
# non-Cygwin Python. If you are using Cygwin Python don't do this because
# it has already been done for you.
cygwin_dll_init = cygwin.cygwin_dll_init
cygwin_dll_init.restype = None
cygwin_dll_init.argtypes = []
cygwin_dll_init()

free = cygwin.free
free.restype = None
free.argtypes = [c_void_p]

CCP_POSIX_TO_WIN_A = 0
CCP_POSIX_TO_WIN_W = 1
CCP_WIN_A_TO_POSIX = 2
CCP_WIN_W_TO_POSIX = 3

def win2posix(path):
    """Convert a Windows path to a Cygwin path"""
    result = cygwin_create_path(CCP_WIN_W_TO_POSIX,xunicode(path))
    if result is None:
        raise Exception("cygwin_create_path failed")
    value = cast(result,c_char_p).value
    free(result)
    return value

def posix2win(path):
    """Convert a Cygwin path to a Windows path"""
    result = cygwin_create_path(CCP_POSIX_TO_WIN_W,str(path))
    if result is None:
        raise Exception("cygwin_create_path failed")
    value = cast(result,c_wchar_p).value
    free(result)
    return value

# Example, convert LOCALAPPDATA to cygwin path and back
from os import environ
localAppData = environ["LOCALAPPDATA"]
print("Original Win32 path: %s" % localAppData)
localAppData = win2posix(localAppData)
print("As a POSIX path: %s" % localAppData)
localAppData = posix2win(localAppData)
print("Back to a Windows path: %s" % localAppData)

关于python - 转换 POSIX->WIN 路径,在 Cygwin Python 中,不调用 cygpath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10884268/

相关文章:

python - Pandas 重新映射到列中的范围

python - 从 numpy 数组中的每个字符串中提取第一个字母

python - 凯撒密码中单个字符不匹配 : Python

c++ - gdb 在 Emacs 中不接受 stdin 重定向

c - gcc:错误:Makfile 中无法识别的命令行选项 '-Wl'

python - python 中的 MIN 函数 - 为什么我会收到此错误?

python - 剥离 Html 标签 Findall + Beautiful Soup

git - 无法在 Windows 上使用 Cygwin 启动 Git GUI

cygwin - 在 cygwin 中循环安装

python - 在 Cygwin/Python2.7 中安装包时出现 pip 错误