1. 程式人生 > >Python:windows封裝的函式

Python:windows封裝的函式

py windows一些封裝函式

1.啟動和殺死程序

1)啟動exe

python中經常會遇到一些函式混淆不清楚

如:os.system,

       os.popen,

       subprocess.popen

下面,我們來一一介紹

os.system 會得到返回值

os.popen 只會得到執行結果而沒有返回值

當然也可以使用commands的命令同時得到返回值和執行結果,但是這個命令漸漸被廢棄

returncode=os.system('cat /home/test')
output=os.popen('cat /home/test')
print output.read()
(status, output) = commands.getstatusoutput('cat /home/test')

python引入subprocess.Popen,相當厲害的一個函式,覆蓋了所有想要實現的功能

subprocess主要是用來代替以下的模組和函式

os.system
os.spawn*
os.popen*
popen2.*
commands.*

首先,subprocess.call代替os.system,

            subprocess.check_output代替os.popen

而subprocess.Popen則是最為全面的一個函式,它包含了stdin,stdout,stderr三個管道,args輸入引數等等

plus.py

a = int(raw_input())
b = int(raw_input())
 
print 'a + b = ', a+b

 python command line

import subprocess
 
p =subprocess.Popen('python C://plus.py', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
 
p.stdin.write('4\n')
p.stdin.write('5\n')
 
print p.stdout.readline()

也可以通過cmd,啟動exe 

def WinStartProcess(exeName,params=""):
    cmd = exeName + " " + params
    try:
        win32api.WinExec(cmd)
    except:
        return False
    return True

2)殺死程序

1. pskill 程序號 殺死程序

2. taskkill 命令較為常見, 可以根據應用程式名稱來殺死程序

TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T]

/S system 指定要連線到的遠端系統。
/U [domain\]user 指定應該在哪個使用者上下文
執行這個命令。
/P [password] 為提供的使用者上下文指定密碼。如果忽略,提示輸入。
/F 指定要強行終止的程序。
/FI filter 指定篩選進或篩選出查詢的的任務。
/PID process id 指定要終止的程序的PID。
/IM image name 指定要終止的程序的影象名。萬用字元 '*'可用來指定所有影象名。
/T Tree kill: 終止指定的程序和任何由此啟動的子程序。
/? 顯示幫助/用法。

taskkill /f /im python.exe /t

3. processshacker可以殺死防毒軟體的程序,較為強大,自行查詢

2.查詢 程式 是否執行

一般情況下在windows中使用WMI,WMI是提供作業系統核心介面的管理支援技術

查詢程式是否執行就是用這種技術

python中主要是利用win32com.client的dispatch函式

service = win32com.client.Dispatch('WbemScripting.SWbemLocator')
server = service.ConnectServer('127.0.0.1', 'root\cimv2', '', '')

具體程式碼如下:

def WinIsAlive(processname):
    pos = processname.find('.')
    if pos == -1: 
        procname = processname + '.exe'
    else:
        procname = processname
    service = win32com.client.Dispatch('WbemScripting.SWbemLocator')
    server = service.ConnectServer('127.0.0.1', 'root\cimv2', '', '')
    ps = server.ExecQuery('select * from Win32_Process')
    exist = 0
    for p in ps:
        if (p.Name.upper() == procname.upper()):
            del service
            return True
    del service
    return False

 3.操作登錄檔

操作登錄檔的方式有兩種,一種是通過python的內建模組_winreg,另一種方式就是Win32 Extension For Python的win32api模組

這裡我們介紹 _winreg

操作動作可以包括 讀取,建立,刪除(key or value)

#直接通過鍵名讀取鍵值
key =_winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r"SOFTWARE\SogouGame")
value,type =_winreg.QueryValueEx(key,"")
value,type =_winreg.QueryValueEx(key,"Version")
 
#否則,遍歷列舉
try:
   i=0
   while 1:
       #EnumValue方法用來列舉鍵值,EnumKey用來列舉子鍵
       name,value,type = _winreg.EnumValue(key,i)
       print repr(name),value,type
       i+=1
exceptWindowsError:
   print

4.獲取視窗控制代碼

通常使用win32gui模組來處理這個問題

1)獲取當前所有視窗的控制代碼,視窗名和類名

##@函式目的: 列舉視窗的回撥函式
##@引數說明:
##@返回值:  視窗控制代碼、視窗名和視窗類名
##@函式邏輯:
def windowEnumerationHandler(hwnd, resultList):
    resultList.append((hwnd, win32gui.GetWindowText(hwnd),win32gui.GetClassName(hwnd)))
 
def windowChildEnumerationHandler(hwnd, resultList):
    resultList.append((hwnd, win32gui.GetWindowText(hwnd), win32gui.GetClassName(hwnd)))
 
##@函式目的: 獲取系統中所有視窗列表
##@引數說明:className:視窗類名;windowname:視窗名;level:搜尋的深度,預設為2。
##@返回值:找到的視窗列表。形式為[(控制代碼,類名,視窗名),...]
##@函式邏輯:  遞迴搜尋視窗列表,預設可以獲取2層。例如搜狗瀏覽器主框架控制代碼和側邊欄控制代碼
def EnumAllWindows(level=2):
    topWindows = []
    win32gui.EnumWindows(windowEnumerationHandler, topWindows)
    findResult = []
    try:
        for oneWnd in topWindows:
            handle = oneWnd[0]
            EnumAllChildWindows(handle,findResult,level)
    except Exception, e:
        None
    return findResult
 
##@函式目的:    獲取一個視窗的子視窗
##@函式引數:   resultList:子視窗列表;level:獲取的子視窗級數。level值越大,則搜尋深度越大
##@引數說明:   
##@返回值:	
def EnumAllChildWindows(handle,resultList,level):
    hlist = []
    if level == 0:
        return
    try:
        resultList.append((handle,win32gui.GetClassName(handle),win32gui.GetWindowText(handle)))
        win32gui.EnumChildWindows(handle,windowChildEnumerationHandler,hlist)
        for cw in hlist:
            EnumAllChildWindows(cw[0],resultList,level-1)
    except:
        None

2)再通過類名或者視窗名來定位控制代碼

def GetHandles(className="", wndName = ""):
  windows = EnumAllWindows(3)
  #f.write(str(windows))
  handles = []
  for window in windows:
    if window[1].lower().find(className.lower()) != -1 and window[2].lower().find(wndName.lower()) != -1:
      handles.append(window[0])
  return handles  

3)做些限制條件,得到specific視窗控制代碼

比如從子視窗限制

#通過類名遞迴搜尋子窗體控制代碼
def SearchSubWindowByClassName(parentWindow,className,keyword2="",keyword3=""): #最多三個限制條件同時滿足
    #先判斷視窗本身是不是要找的
    try:
        if parentWindow == 0:
            return 0
        ctrlClassName = win32gui.GetClassName(parentWindow)
        if str(ctrlClassName).lower().find(str(className).lower()) != -1:
            if str(ctrlClassName).lower().find(keyword2) != -1 and str(ctrlClassName).lower().find(keyword3) != -1:
                return parentWindow
        start = None
        #如果有子視窗則迴圈每個子視窗
        while True:
          #對每個子視窗遞迴
          start = FindSubWindow(parentWindow,start,None,None)
          if start==0:
            break
          winHwnd = SearchSubWindowByClassName(start,className,keyword2,keyword3)
          if winHwnd != 0:
            return winHwnd
          return 0
    except:
        return 0
 
def FindSubWindow(parentHwnd,startHwnd,className,windowName):
    try:
        return win32gui.FindWindowEx(parentHwnd,startHwnd,className,windowName)
    except:
        return 0

其實,不只是上面的方法可以獲取handle,有多種方式可以獲取handle,python可以靈活方便地處理windows視窗 

5.滑鼠

1)滑鼠移動

def MouseTo(x,y):
    win32api.SetCursorPos((x,y))

2)滑鼠點選

def Click(mtype="LEFT"):
    mtype = mtype.upper()
    if mtype == "LEFT":
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)
        time.sleep(0.2)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)
    elif mtype == "RIGHT":
        win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,0,0,0,0)
        time.sleep(0.2)
        win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,0,0,0,0)
    elif mtype == "MIDDLE":
        win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEDOWN,0,0,0,0)
        time.sleep(0.2)
        win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEUP,0,0,0,0)

6.視窗位置和大小

獲取視窗四個畫素點的方法

def GetWindowRect(handle):
    if handle == None or handle == 0:
        return []
    try:
        return win32gui.GetWindowRect(handle)
    except:
        return []

 返回一個list,包含四個數字,指相對螢幕0,0的位置,具體相對位置從下面的函式可以推敲出來

def GetStartPoint(handle, relativeX, relativeY):
  rect = GetWindowRect(handle)
  if relativeX == Position.LEFT:
    x = rect[0]
  elif relativeX == Position.RIGHT:
    x = rect[2]
  else:
    x = (rect[0] / rect[2]) / 2
	
  if relativeY == Position.TOP:
    y = rect[1]
  elif relativeY == Position.BOTTOM:
    y = rect[3]
  else:
    y = (rect[1] / rect[3]) / 2 
  return (x, y)

另外,如果客戶端軟體全屏,則rect[0]和rect[1]會為負數,且為-8

但是 chrome 只有rect[0]為-1

def IsFullScreen(handle):
    rect = GetWindowRect(handle)
    return rect[0] <= 0 and rect[1] <= 0

http://www.cppblog.com/aurain/archive/2009/03/10/76126.aspx 

轉載自部落格:https://blog.csdn.net/luan_tianjiao/article/details/19113331