Pythonを使用してアクティブウィンドウを画面に表示したいのですが。
たとえば、ユーザー名とパスワードをadminとして入力するルーターの管理インターフェイス
その管理インターフェイスは、ユーザー名とパスワードの入力を自動化するためにpythonを使用してキャプチャしたいものです。
これを行うには、どのようなインポートが必要ですか?
Windowsでは、python for windows extensions( http://sourceforge.net/projects/pywin32/ )を使用できます):
from win32gui import GetWindowText, GetForegroundWindow
print GetWindowText(GetForegroundWindow())
以下のコードはpython 3:
from win32gui import GetWindowText, GetForegroundWindow
print(GetWindowText(GetForegroundWindow()))
(これは http://scott.sherrillmix.com/blog/programmer/active-window-logger/ にあります)
次のスクリプトは、Linux、Windows、Macで動作するはずです。現在、Linux(Ubuntu Mate Ubuntu 15.10)でのみテストされています。
Linuxの場合:
インストールwnck
(Sudo apt-get install python-wnck
Ubuntuで libwnck を参照)
Windowsの場合:
確認してください win32gui
利用可能です
Macの場合:
AppKit
が利用可能であることを確認してください
#!/usr/bin/env python
"""Find the currently active window."""
import logging
import sys
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
level=logging.DEBUG,
stream=sys.stdout)
def get_active_window():
"""
Get the currently active window.
Returns
-------
string :
Name of the currently active window.
"""
import sys
active_window_name = None
if sys.platform in ['linux', 'linux2']:
# Alternatives: http://unix.stackexchange.com/q/38867/4784
try:
import wnck
except ImportError:
logging.info("wnck not installed")
wnck = None
if wnck is not None:
screen = wnck.screen_get_default()
screen.force_update()
window = screen.get_active_window()
if window is not None:
pid = window.get_pid()
with open("/proc/{pid}/cmdline".format(pid=pid)) as f:
active_window_name = f.read()
else:
try:
from gi.repository import Gtk, Wnck
gi = "Installed"
except ImportError:
logging.info("gi.repository not installed")
gi = None
if gi is not None:
Gtk.init([]) # necessary if not using a Gtk.main() loop
screen = Wnck.Screen.get_default()
screen.force_update() # recommended per Wnck documentation
active_window = screen.get_active_window()
pid = active_window.get_pid()
with open("/proc/{pid}/cmdline".format(pid=pid)) as f:
active_window_name = f.read()
Elif sys.platform in ['Windows', 'win32', 'cygwin']:
# http://stackoverflow.com/a/608814/562769
import win32gui
window = win32gui.GetForegroundWindow()
active_window_name = win32gui.GetWindowText(window)
Elif sys.platform in ['Mac', 'darwin', 'os2', 'os2emx']:
# http://stackoverflow.com/a/373310/562769
from AppKit import NSWorkspace
active_window_name = (NSWorkspace.sharedWorkspace()
.activeApplication()['NSApplicationName'])
else:
print("sys.platform={platform} is unknown. Please report."
.format(platform=sys.platform))
print(sys.version)
return active_window_name
print("Active window: %s" % str(get_active_window()))
このようなタスクでは、外部の依存関係をインポートする必要はありません。 Pythonには、かなりきちんとした外部関数インターフェイスが付属しています- ctypes
これにより、C共有ライブラリをネイティブで呼び出すことができます。ほとんどの特定のバインディングも含まれています一般的なWin32 DLL。
例えば。 foregorundウィンドウのPIDを取得するには:
import ctypes
from ctypes import wintypes
user32 = ctypes.windll.user32
h_wnd = user32.GetForegroundWindow()
pid = wintypes.DWORD()
user32.GetWindowThreadProcessId(h_wnd, ctypes.byref(pid))
print(pid.value)
Linuxユーザーの場合:提供されたすべての回答には、インストール時に多数のエラーが発生する(「pip」がビルドに失敗する)「wx」などの追加モジュールが必要でしたが、このソリューションを簡単に変更できました-> 元のソース 。オリジナルにバグがありました( 正規表現のPython TypeError )
import sys
import os
import subprocess
import re
def get_active_window_title():
root = subprocess.Popen(['xprop', '-root', '_NET_ACTIVE_WINDOW'], stdout=subprocess.PIPE)
stdout, stderr = root.communicate()
m = re.search(b'^_NET_ACTIVE_WINDOW.* ([\w]+)$', stdout)
if m != None:
window_id = m.group(1)
window = subprocess.Popen(['xprop', '-id', window_id, 'WM_NAME'], stdout=subprocess.PIPE)
stdout, stderr = window.communicate()
else:
return None
match = re.match(b"WM_NAME\(\w+\) = (?P<name>.+)$", stdout)
if match != None:
return match.group("name").strip(b'"')
return None
if __name__ == "__main__":
print(get_active_window_title())
利点は、追加のモジュールなしで機能することです。複数のプラットフォーム間で動作させる場合は、コマンドと正規表現文字列を変更して、プラットフォームに基づいて必要なデータを取得するだけです(上記の標準のif/elseプラットフォーム検出を使用sys.platform)。
余談ですが、「Sudo apt-get install python-wnck」を使用してインストールした場合、インポートwnckはpython2.xでのみ機能します。python3.xを使用していたため、テストしていないpypieしかオプションがありませんでした。これが他の誰かを助けることを願っています。
ctypesを使用してWindows APIを操作する方法を示したNunoAndréの回答に感謝します。私は彼のヒントを使用して実装例を書きました。
ctypes
ライブラリは、Pythonに含まれています。v2.5以降です。つまり、ほとんどすべてのユーザーがこのライブラリを持っています。そして、win32gui
のような古くて使用されていないライブラリよりもクリーンなインターフェイスですこの記事の執筆時点で2017年)。
ドキュメントはこちら: https://docs.python.org/3/library/ctypes.html (独自のコードを記述したい場合は、使用方法のヘルプを読む必要があります。そうしないと、セグメンテーション違反のクラッシュが発生する可能性があります、へへ。)
基本的に、ctypesには、最も一般的なWindows DLLのバインディングが含まれています。これは、外部ライブラリを必要とせずに、純粋なPythonでフォアグラウンドウィンドウのタイトルを取得する方法です。組み込みのctypeだけです! :-)
Ctypesの最もクールな点は、必要なものすべてに対してGoogleanyWindows APIを実行できることです。それを使用したい場合は、canctypesを介して実行してください!
Python 3コード:
from typing import Optional
from ctypes import wintypes, windll, create_unicode_buffer
def getForegroundWindowTitle() -> Optional[str]:
hWnd = windll.user32.GetForegroundWindow()
length = windll.user32.GetWindowTextLengthW(hWnd)
buf = create_unicode_buffer(length + 1)
windll.user32.GetWindowTextW(hWnd, buf, length + 1)
# 1-liner alternative: return buf.value if buf.value else None
if buf.value:
return buf.value
else:
return None
パフォーマンスは非常に良好です。私のコンピューターでは0.01
MILLISECONDS(0.00001
秒)。
Python 2でも非常に小さな変更を加えて機能します。Python 2を使用している場合は、型注釈(from typing import Optional
および-> Optional[str]
)。:-)
楽しい!
Win32技術説明:
length
変数は、UTF-16(Windows Wide "Unicode")のactualテキスト文字の長さです。( BYTESの数ではありません。)Cスタイルの文字列の最後にnullターミネータ用のスペースを追加するには、+ 1
を追加する必要があります。そうしないと、実際のテキストの最終的な実際の文字に合わせてバッファに十分なスペースがなくなり、Windowsは返された文字列を切り捨てます(これは、非常に重要な最終文字列Nullに合うようにするためです) -ターミネーター)。
create_unicode_buffer
関数は、その数のUTF-16文字にスペースを割り当てます。
ほとんど(またはすべて?常にMicrosoftのMSDNドキュメントを読んでください!)Unicodeテキストに関連するWindows APIは、バッファ長を文字としてバイトとしてではありません。
また、関数呼び出しをよく見てください。一部はW
で終わります(GetWindowTextLengthW
など)。これは、Unicode文字列のWindows名である「ワイド文字列」を表します。これらのW
呼び出しを実行して、適切なUnicode文字列を取得することが非常に重要です(国際文字をサポートしています)。
PS:Windowsは長い間Unicodeを使用しています。 Windows 10は完全にUnicodeであり、W
関数呼び出しのみを必要とするという事実は知っています。古いバージョンのWindowsがotherマルチバイト文字列形式を使用したときの正確な締切日はわかりませんが、Windows Vistaより前であると思いますが、誰が気にかけますか?古いバージョンのWindows(7と8.1も含む)は死んでおり、Microsoftはサポートしていません。
もう一度...お楽しみください! :-)
それが役立つ場合に備えて追加したかったのですが、私には自分のプログラム用の機能があります(これは私のPCの照明用のソフトウェアで、次の単純な数行の機能があります:
def isRunning(process_name):
foregroundWindow = GetWindowText(GetForegroundWindow())
return process_name in foregroundWindow