如何关闭xxxxx.exe终端窗口而不杀死xxxxx进程?

时间:2013-08-20 08:14:01

标签: emacs terminal stdout createprocess

这个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的/ sh.exe的交互式终端,而不会破坏Python进程?

我试图通过浅略深入了解make-comint-in-buffer的源代码,但碰到processp,这是C编译代码,其来源我不能find

我提出这个问题的原因是在不使用pythonw的情况下找到this问题的替代答案(例如,他们不是mayapyw.exemayapy.exe。< / p>

2 个答案:

答案 0 :(得分:1)

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

create_child in w32proc.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))
{ ...
}

答案 1 :(得分:0)

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

这会强制您在脚本中导入/或包含这段代码,然后调用函数/在脚本中执行一些操作。运行脚本后,应隐藏提示。请参阅"main.py" - 部分内容以供使用。

<强> Window.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)

<强> main.py

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.

我希望这可以解决问题。