0

这个 Emacs 命令(make-comint-in-buffer "Python" nil "python" nil "-i")或如何(make-comint-in-buffer "git" nil "C:/Program Files (x86)/Git/bin/sh.exe" nil "--login" "-i")设法在 Emacs 缓冲区中获取提示并在不终止 Python 进程的情况下使用它的 Python/sh.exe 交互式终端?

make-comint-in-buffer我试图通过对's source code的浅层研究来弄清楚,但遇到了processpC 编译代码,我找不到它的源代码。

我问这个问题的原因是在不使用的情况下找到这个pythonw问题的替代答案(例如,他们的 aint a mayapyw.exeto mayapy.exe)。

4

2 回答 2

1

Emacs 使用 SHOWWINDOW 标志来 CreateProcess 来控制与子进程关联的控制台窗口的显示。

create_childw32proc.c中的关键代码是:

if (NILP (Vw32_start_process_show_window) && !is_gui_app)
    start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
else
    start.dwFlags = STARTF_USESTDHANDLES;

start.wShowWindow = SW_HIDE;

if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, flags, env, dir, &start, &cp->procinfo))
{ ...
}
于 2013-08-21T01:33:43.700 回答
0

我只能猜测 Emacs 命令是如何工作的,因此无法真正帮助您……但是,我可以为您提供一种隐藏窗口的方法。这可以通过使用 CTypes 模块并调用 Windows-API 来获取 Window/Python-prompts ID/Hwin,然后隐藏该窗口来实现。

这迫使您在脚本中导入/或包含这段代码,然后在脚本中调用一个函数/做一些事情。一旦你的脚本运行,这应该隐藏提示。请参阅"main.py"-part 了解用法。

窗口.py

from ctypes import *

user32 = windll.user32

BOOL    = c_bool
INT     = c_int
LONG    = c_long
LPVOID  = c_void_p
LPTSTR  = c_wchar_p
HWND    = LPVOID
LPARAM  = LPVOID

GW_OWNER = 4
GWL_EXSTYLE  = -20
WS_EX_TOOLWINDOW = 128
WS_EX_APPWINDOW = 262144

#------------------------------------------------------------------------ 

def GetWindowLong(hwnd, index):
    user32.GetWindowLongW.argtypes = [HWND, INT]
    return user32.GetWindowLongW(hwnd, index)

def GetWindow(hWnd, uCmd):
    user32.GetParent.argtypes = [HWND, INT]
    return user32.GetWindow(hWnd, uCmd)

def GetParent(hwnd):
    user32.GetParent.argtypes = [HWND]
    return user32.GetParent(hwnd)

def IsWindowVisible(hwnd): 
    user32.IsWindowVisible.argtypes = [HWND]
    return user32.IsWindowVisible(hwnd)

def GetWindowTextLength(hwnd):
    user32.GetWindowTextLengthW.argtypes = [HWND]
    return user32.GetWindowTextLengthW(hwnd)

def GetWindowText(hwnd):
    length = GetWindowTextLength(hwnd)
    if not length: return False
    buff = create_unicode_buffer(length + 1)
    user32.GetWindowTextW.argtypes = [HWND, LPTSTR, INT]
    res = user32.GetWindowTextW(hwnd, buff, length + 1)   
    if res: return buff.value
    else: return False  

def isRealWindow(hwnd):
    """ Check if a given window is a real Windows application frame..
        Returns a BOOL """

    if not IsWindowVisible(hwnd):
        return False
    if GetParent(hwnd) != 0:
        return False
    hasNoOwner = GetWindow(hwnd, GW_OWNER) == 0
    lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
    if (((lExStyle & WS_EX_TOOLWINDOW) == 0 and hasNoOwner)
      or ((lExStyle & WS_EX_APPWINDOW != 0) and not hasNoOwner)):
        if GetWindowText(hwnd):
            return True
    return False

class WindowEnumerator(object):
    """ Window enumerator class.  You can pass it's instances
        as callback functions in window enumeration APIs. """

    def __init__(self):
        self.hwnd = []

    def __call__(self, hwnd, lParam):
        self.hwnd.append(hwnd)
        return True

class __EnumWndProc(WindowEnumerator):
    pass

def EnumWindows():
    WNDENUMPROC = WINFUNCTYPE(BOOL,HWND,LPARAM)
    _EnumWindows = user32.EnumWindows
    _EnumWindows.argtypes = [WNDENUMPROC, LPARAM]
    _EnumWindows.restype  = BOOL

    EnumFunc = __EnumWndProc()
    lpEnumFunc = WNDENUMPROC(EnumFunc)
    if not _EnumWindows(lpEnumFunc, None):
        errcode = GetLastError()
        if errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
            raise WinError(errcode)
    return EnumFunc.hwnd

def GetWindowByName(title):
    window = []
    hwnds = EnumWindows()
    for hwnd in hwnds:
        if not isRealWindow(hwnd):
            pass
        else:
            wndtitle = GetWindowText(hwnd)
            if title.lower() in wndtitle.lower():
                return (hwnd, wndtitle)
    return False

def ShowWindow(hWnd, arg=0):
    user32.ShowWindow.argtypes = [HWND, c_int]
    return user32.ShowWindow(hWnd, arg)

主文件

import Window

# Pass the full or partial title of the window that should be hidden.
wnd = Window.GetWindowByName('xxxxxxx.exe')
if wnd:
    Window.ShowWindow(wnd[0], 0) #Hide it. 0=SW_HIDE, 5 = SW_SHOW.

我希望这能解决问题。

于 2013-08-20T10:16:37.983 回答