4

次のコード ブロックを実行すると、GetPixel は毎回約 10,000 回目の呼び出しでエラーをスローし始めます。コードを try-except ステートメントに入れると、最初の失敗の後のすべての呼び出しが失敗します。回復する唯一の方法は、スクリプトを終了して再度実行することです。通話の間に短い睡眠を入れてみました。呼び出しの間にガベージ コレクションをトリガーしようとしました。IDE からスタンドアロン プロセスとしてスクリプトを実行してみました。何か案は?スクリプトを実行して、失敗した場合に報告することも役に立ちます。

import gc
import os
import time
import win32api, win32con, win32gui
import sys
import win32com.client

terms = 0

def get_pixel_colour(i_x, i_y):
    i_desktop_window_id = win32gui.GetDesktopWindow()
    i_desktop_window_dc = win32gui.GetWindowDC(i_desktop_window_id)
    long_colour = win32gui.GetPixel(i_desktop_window_dc, i_x, i_y)
    i_colour = int(long_colour)
    return (i_colour & 0xff), ((i_colour >> 8) & 0xff), ((i_colour >> 16) & 0xff)


for x in range (0, 1000000):
    colour = get_pixel_colour(500, 500)
    terms = terms + 1
    print terms

返されるエラーは

error: (0, 'GetPixel', 'No error message is available')
4

1 に答える 1

3

i_desktop_windw_dc オブジェクトがガベージ コレクションされているときに、リソースが解放されていないと思われます。releaseDC の呼び出しが必要なのかもしれませんが、pywin32 をインストールした後、自分のシステムで短い検索を行った後、ドキュメントやソース コードが見つかりませんでした。win32gui には ReleaseDC 関数がありますが、それを使用して、win32gui.GetWindowDC を介して取得したデバイス コンテキストを解放することになっていると推測できます。

これは回避策かもしれません:

import gc
import os
import time
import win32api, win32con, win32gui
import sys
import win32com.client

terms = 0
class DesktopWindow(object):
    def __init__(self, *args, **kwargs):
        self.window_id = win32gui.GetDesktopWindow()
        self.window_dc = win32gui.GetWindowDC(self.window_id)
        pass
    def get_pixel_color(self, i_x, i_y):
        long_colour = win32gui.GetPixel(self.window_dc, i_x, i_y)
        i_colour = int(long_colour)
        return (i_colour & 0xff, (i_colour >> 8) & 0xff,
                (i_colour >> 16) & 0xff)

dtop = DesktopWindow()

for x in range (0, 1000000):
    colour = dtop.get_pixel_color(500, 500)
    terms = terms + 1
    if terms % 100 == 0:
        print terms

入力すると、ここで 200,000 回の get_pixel_color 操作が実行されます。

win32gui.ReleaseDC(i_desktop_window_id, i_desktop_window_dc)また、スタンドアロン関数の最後で試して、それが役立つかどうかを確認してください。(これは、WinAPI コーディングで行うべきことです...完了したらすぐに DC を解放します。)

注: 上記の修正... ReleaseDC の呼び出しには、ウィンドウ ハンドル (hWnd=window id)とデバイス コンテキスト ハンドル (hDC) が必要です。http://msdn.microsoft.com/en-us/library/windows/desktop/dd162920%28v=vs.85%29.aspxを参照してください。

于 2013-10-27T22:32:45.403 に答える