转换POSIX-> WIN路径,在Cygwin Python,w / o调用cygpath [英] Convert POSIX->WIN path, in Cygwin Python, w/o calling cygpath

查看:311
本文介绍了转换POSIX-> WIN路径,在Cygwin Python,w / o调用cygpath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Python脚本,在Cygwin Python构建中运行,以创建发布到本机Windows实用程序(不是Cygwin感知)的命令。这需要在发出命令之前将路径参数从POSIX转换为WIN形式。

I use a Python script, running in a Cygwin build of Python, to create commands issued to native Windows utilities (not Cygwin-aware). This requires conversion of path parameters from POSIX to WIN form before issuing the command.

调用cygpath实用程序是最好的方法,因为它使用Cygwin做

Calling the cygpath utility is the nicest way to do this, since it uses Cygwin to do what it's there to do, but it's also a little horrifying (and slow).

我已经在运行一个Cygwin Python构建 - 所以代码做转换是当下。看起来应该有一个Cygwin / Python特定的扩展,给我一个钩子这种能力,直接在Python中,而不必启动一个全新的过程。

I'm already running a Cygwin build of Python - so the code to do the conversion is present. It seems like there should be a Cygwin/Python specific extension that gives me a hook to this capability, directly in Python, without having to fire up a whole new process.

推荐答案

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

This is possible by calling the Cygwin API using ctypes. The below code works for me–I am using 64-bit cygwin DLL version 2.5.2 on Windows 2012, and this works on the Cygwin versions of both Python 2.7.10 and Python 3.4.3.

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

Basically we call cygwin_create_path from cygwin1.dll to perform the path conversion. That function allocates a memory buffer (using malloc) containing the converted path. So then we need to use free from cygwin1.dll to release the buffer it allocated.

请注意,下面的 xunicode 是一个穷人的替代 six (一个Python 2/3兼容性库);如果你需要支持Python 2和3,六是更好的答案,但我想我的例子是没有依赖任何非捆绑的模块,这就是为什么我这样做。

Note that xunicode below is a poor man's alternative to six (a Python 2/3 compatibility library); if you need to support both Python 2 and 3, six is the much better answer, but I wanted my example to be free of dependencies on any non-bundled modules which is why I did it this way.

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)

这篇关于转换POSIX-> WIN路径,在Cygwin Python,w / o调用cygpath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆