Python 让Win32 MessageBox显示在其他程序上

Python 让Win32 MessageBox显示在其他程序上,python,windows,user-interface,Python,Windows,User Interface,我最近开始学习Python,并编写了一个小脚本,在某个网站更改内容时通知我。然后,我将其作为计划任务添加到Windows中,以便它可以每10分钟运行一次。我希望网站立即更改,因此我添加了一个win32ui消息框,如果脚本检测到网站已更改,该消息框将弹出。下面是我在MessageBox中使用的小代码片段(我知道,是富有想象力的文本): 我的问题是,我大部分时间都在使用远程桌面,所以当MessageBox弹出时,它会位于远程桌面会话的后面,有没有办法强制MessageBox显示在它上面 类似地,当脚

我最近开始学习Python,并编写了一个小脚本,在某个网站更改内容时通知我。然后,我将其作为计划任务添加到Windows中,以便它可以每10分钟运行一次。我希望网站立即更改,因此我添加了一个win32ui消息框,如果脚本检测到网站已更改,该消息框将弹出。下面是我在MessageBox中使用的小代码片段(我知道,是富有想象力的文本):

我的问题是,我大部分时间都在使用远程桌面,所以当MessageBox弹出时,它会位于远程桌面会话的后面,有没有办法强制MessageBox显示在它上面

类似地,当脚本运行时,命令行会在远程桌面会话上短暂打开(我不希望这样),有没有办法停止这种行为


我对Windows特定的解决方案很满意,因为我知道这可能意味着与窗口管理器打交道,或者可能是一种通知我而不是使用MessageBox的替代方式。

使MessageBox系统处于模式将导致它在每个应用程序上弹出,但在它被关闭之前,无法与任何应用程序交互。考虑创建一个自定义对话框窗口,你可以把它带到前面,或者使用一个通知泡泡来代替。

< P>当你从任务调度器启动任何东西时,Windows会阻止任何“简单”的方法把你的窗口或对话框放在上面。
  • 第一种方式-使用
    MB_SYSTEMMODAL
    (4096值)标志。根据我的经验,它使Msg对话框“始终在顶部”

  • 第二种方法-尝试通过以下调用将控制台/窗口/对话框置于最前面。当然,如果您使用
    MessageBox
    ,则在调用
    MessageBox
    之前,必须这样做(对于您自己创建的窗口)

    SetForegroundWindow(Wnd);
    BringWindowToTop(Wnd);
    SetForegroundWindow(Wnd);
    
  • 至于控制台窗口的闪烁,您可以尝试在隐藏状态下启动Python。例如,使用“HidCon”或。参考它们的参数,例如:

    ConEmu -basic -MinTSA -cmd C:\Python27\python.exe C:\pythonScript.py
        or
    CMDOW /RUN /MIN C:\Python27\python.exe C:\pythonScript.py
    

    通过使用
    pyw
    扩展名来命名脚本,而不是简单地使用
    py
    来避免命令窗口闪烁。您也可以使用
    pythonw.exe
    而不是
    python.exe
    ,这实际上取决于您的需求


    请参见

    Windows试图使在活动应用程序上弹出窗口变得困难。用户觉得这很烦人,尤其是因为中断窗口通常会窃取键盘焦点

    Windows发出此类通知的方法是在通知区域中使用气球,而不是消息框。通知气球不会窃取焦点,而且(据推测)不会太分散注意力


    我不确定python Windows UI库是否为提供包装。

    使用ctypes它会显示一个Windows错误消息框,非常易于使用

    import ctypes
    if condition:
        ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
    
    这对我很有用:

    from ctypes import *
    def MessageBox(title, text, style):
        sty = int(style) + 4096
        return windll.user32.MessageBoxW(0, text, title, sty) #MB_SYSTEMMODAL==4096
        ## Button Styles:
        ###  0:OK  --  1:OK|Cancel -- 2:Abort|Retry|Ignore -- 3:Yes|No|Cancel -- 4:Yes|No -- 5:Retry|No -- 6:Cancel|Try Again|Continue
        ## To also change icon, add these values to previous number
        ### 16 Stop-sign  ### 32 Question-mark  ### 48 Exclamation-point  ### 64 Information-sign ('i' in a circle)
    
    用法:
    借助Python和MSG命令(在Win10上工作),非常简单的模态异步消息框:

    在Python中,我一直在使用
    子进程
    发送CMD命令,允许我读取和处理输出,查找错误等

    import subprocess as sp
    
    name = 'Lucas'
    message = f'Express yourself {name} in 255 characters ;)'
    command = f'msg /server:192.168.0.110 * /v /time:360 "{message}"'
    output = str(sp.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
    
    if 'returncode=0' in output:
        pint('Message sent')
    else:
        print('Error occurred. Details:\n')
        print(output[output.index('stdout=b'):])
    

    事实上,“但在它被驳回之前,任何人都无法与之互动”。MB_SYSTEMMODAL意味着MessageBox将“始终位于顶部”。就这些。有没有办法打开一个消息框,强制与之交互?我只是在想,如果我在远程桌面上工作,我会点击很多次,如果弹出窗口出现在我的另一个显示器上并且很快被最小化,我很可能会错过它。你可以根据需要随时打开气泡。如果这行得通,那就太好了。谢谢,我明天才能尝试,但到时候会回复你。有没有想过如何防止命令窗口在RDP会话中弹出,或者我必须接受它?让它每10分钟弹出一次,这只是一个小小的麻烦,而不是一个大问题。在任务调度程序中,我调用了类似“C:\Python27\python.exe C:\pythonScript.py”的东西,它运行脚本并在关闭前使命令行弹出一小会儿。好主意,我想知道不同的版本是用来做什么的。我认为即使Python提供了一个通知包装器,这个通知也不会出现在远程桌面会话的后面,不是吗?尽管Outlook设法使通知以某种方式显示在RDP会话的左上角,但请在确认问题在您这边之后删除上述注释。
    from ctypes import *
    def MessageBox(title, text, style):
        sty = int(style) + 4096
        return windll.user32.MessageBoxW(0, text, title, sty) #MB_SYSTEMMODAL==4096
        ## Button Styles:
        ###  0:OK  --  1:OK|Cancel -- 2:Abort|Retry|Ignore -- 3:Yes|No|Cancel -- 4:Yes|No -- 5:Retry|No -- 6:Cancel|Try Again|Continue
        ## To also change icon, add these values to previous number
        ### 16 Stop-sign  ### 32 Question-mark  ### 48 Exclamation-point  ### 64 Information-sign ('i' in a circle)
    
    MessageBox('Here is my Title', 'Message to be displayed', 64)
    
    # In CMD (you may use Username logged on target machine instead of * to send message to particular user):
    msg /server:IP_or_ComputerName * /v /time:appearance_in_secs Message_up_to_255_chars 
    # I.e. send "Hello everybody!" to all users on 192.168.0.110 disappearing after 5 mins 
    msg /server:192.168.0.110 * /v /time:300 "Hello everybody!"
    
    import subprocess as sp
    
    name = 'Lucas'
    message = f'Express yourself {name} in 255 characters ;)'
    command = f'msg /server:192.168.0.110 * /v /time:360 "{message}"'
    output = str(sp.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
    
    if 'returncode=0' in output:
        pint('Message sent')
    else:
        print('Error occurred. Details:\n')
        print(output[output.index('stdout=b'):])