2012-01-13 32 views
10

Tôi có một chương trình với giao diện GUI có thiết lập ban đầu mà tôi cần thực hiện theo cách thủ công. AutoIt đã rất hữu ích cho đến nay, vì nó cung cấp các cách rất dễ dàng để làm việc ngay cả với các đối tượng GUI phức tạp để truy cập (danh sách thả xuống, các menu xuất hiện trên di chuột, vv).Bắt Python và AutoIT để làm việc cùng nhau bằng cách sử dụng win32com: có gì với những cửa sổ xử lý?

Tuy nhiên, tập lệnh mà cuối cùng tôi sẽ cần để thiết lập chương trình sẽ cần phải được chuyển một mảng/danh sách biến lớn - có của các cài đặt khác nhau cần được thay đổi.

Tôi đã thiết lập logic để quyết định những biến được thiết lập nào sẽ sử dụng tập lệnh Python. Bây giờ tôi đang cố gắng tìm ra cách để Python và AutoIt nói chuyện với nhau.

Gọi tập lệnh AutoIt tùy chỉnh từ dòng lệnh bằng cách sử dụng Python phần lớn là do câu hỏi vì số lượng lớn các biến cần được chuyển. Không cảm thấy đẹp. Tôi có thể thử và có Python viết một tập tin chìa khóa AutoIt, sau đó AutoIt có thể đọc để thiết lập các biến ban đầu của nó, nhưng tôi muốn chắc chắn rằng tôi đã hết tất cả các tùy chọn để Python làm việc trực tiếp với AutoIt trước.

Để kết thúc, tôi đã cố gắng sử dụng Python cùng với thư viện win32com để giao tiếp với AutoIt. Mọi thứ dường như hoạt động tốt - miễn là tôi tham khảo các cửa sổ/menu/đối tượng bằng các tiêu đề chuỗi của chúng hơn là các ký tự (bộ nhớ?) Của chúng. Điều này là có vấn đề, vì các kịch bản cài đặt của tôi có thể chạy song song, thiết lập hai hoặc nhiều tệp riêng biệt cùng một lúc. Nếu đúng như vậy, việc mở một hộp có chuỗi tiêu đề "Mở tệp ..." trong mỗi tệp cùng một lúc có thể gây nhầm lẫn cho mọi thứ. Một cách rõ ràng để giải quyết vấn đề này trong AutoIt là làm việc với "xử lý" của các đối tượng được đề cập, mà tôi tin là địa chỉ bộ nhớ của một số loại, chứ không phải là các tiêu đề chuỗi của chúng. Tôi đoán đây là những địa chỉ bộ nhớ như công cụ AutoIt Window Info, khi được trỏ tới một tùy chọn Window/GUI cụ thể liệt kê một số thập lục phân làm giá trị xử lý của đối tượng.

AutoIt có bộ chức năng nhận được xử lý cửa sổ, menu, v.v. Chúng được triển khai trong AutoIt COM dll, nhưng tôi không thể làm cho chúng hoạt động trong Python. Các hàm xử lý trả về một đối tượng unicode trong Python, không phải là một chuỗi hex như trong AutoIt. Tôi nghĩ rằng đây là lý do tại sao các chức năng mà sau đó cố gắng sử dụng "xử lý" này trong Python không hoạt động.

Ví dụ:

autoIt = win32com.client.Dispatch("AutoItX3.Control") 
windowHandle = autoIt.WinGetHandle(knownWindowTitle) 
returnedWindowTitle = autoIt.WinGetTitle(windowHandle) 

Thông thường, returnedWindowTitle và knownWindowTitle không phù hợp như returnedWindowTitle luôn có vẻ là "0". mũ đang xảy ra ở đây?

Có cách nào khác để tôi gọi các chức năng AutoIt tùy chỉnh ngoài việc sử dụng win32com, dòng lệnh hoặc sử dụng một keytile AutoIt không?

Cảm ơn sự giúp đỡ của bạn.

EDIT: Tôi quên đề cập đến các chuỗi unicode thực tế khớp với các số thập lục phân mà tôi nhận được khi tôi in biến xử lý trong AutoIt.

Ví dụ, trong Python, biến xử lý khi in ra cho tôi u'000C0326 '. Trong AutoIt nó mang lại cho tôi '0x000C0326'.

EDIT: Một số thử nghiệm dựa trên đề xuất của Mat:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control") 
In: mainWindowTitle = "Untitled" 
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle) 
In: mainWindowHandle 
Out: u'000204AC' 
In: testHandle = int(mainWindowHandle, 16) 
In: testHandle 
Out: 132268 
In: autoIt.WinGetTitle(testHandle) 
Out: u'0' 

EDIT: Tôi phát hiện ra các loại của đối tượng cửa sổ xử lý: đó là một đối tượng Microsoft HWND. AutoIt có một hàm có thể "chuyển đổi" một số 16 cơ sở thành một đối tượng HWND (tức là tìm đối tượng HWND với bộ nhớ số 16/xử lý/v.v.). Chỉ cần may mắn của tôi rằng họ đã không đặt chức năng đó vào AutoItX (dll COM). Vì vậy, nếu tôi thực sự muốn chạy với điều này, tôi sẽ phải cố gắng và tìm ra cách để trả lại bất kỳ đối tượng nào được trỏ đến bởi địa chỉ cơ sở 16, và sau đó chuyển nó đúng cách để AutoItX? Tôi có lẽ nghe rất bối rối, bởi vì tất cả điều này không phải là siêu rõ ràng trong đầu của tôi ngay bây giờ.

+0

Có thể là sự cố với các loại ... Tôi không phải là người dùng python, nhưng bạn có thể chạy một số kiểm tra về loại biến 'windowHandle'. Nó phải là một số nguyên. – Matt

+0

@Mat Trong Python, kiểu của biến 'windowHandle' là một chuỗi unicode (ví dụ' u'000C0326''). Số nguyên có phải là số thập lục phân (ví dụ: ''0x000C0326'') (ở dạng số nguyên) mà AutoIt in ra nếu được yêu cầu xuất ra biến' windowHandle'? –

+0

Có. Nếu bạn vượt qua một chuỗi sau đó AutoIt sẽ cố gắng tìm một cửa sổ có tiêu đề phù hợp với chuỗi đó.Trong trường hợp này không có cửa sổ nào được tìm thấy là không có cửa sổ nào tồn tại với tiêu đề "000C0326". Từ thời gian ngắn của tôi với python bạn muốn thử 'autoIt.WinGetTitle (int (windowHandle, 16))' hoặc một cái gì đó dọc theo những dòng, bạn sẽ biết tốt hơn so với tôi. Nếu điều đó không làm việc, thì bạn sẽ cần phải tìm một số cách để có được một loại xử lý tự động trong python. – Matt

Trả lời

2

Vì lợi ích của tìm kiếm, tôi sẽ đăng giải pháp mà tôi đã tìm thấy.

Dưới đây là các mã:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control") 
In: autoIt.AutoItSetOption("WinTitleMatchMode", 4) 
In: mainWindowTitle = "Untitled" 
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle) 
In: mainWindowHandle 
Out: u'000204AC' 
In: testHandle = "[HANDLE:%s]" % mainWindowHandle 
In: autoIt.WinGetTitle(testHandle) 
Out: u'Untitled - Notepad' 

autoIt.AutoItSetOption("WinTitleMatchMode", 4) nói AutoIt để sử dụng phù hợp với danh hiệu tiên tiến, cho phép chúng ta xác định một tay cầm cửa sổ với [HANDLE:000204AC] chuỗi.

Không cần phải xử lý cửa sổ thực tế ở đây.

Nhân tiện, tôi đã phát hiện ra giải pháp này bằng cách dò dẫm trên this forum post. Tôi đã nhận thấy rằng việc tìm kiếm các ngôn ngữ cụ thể của tôi thường rất hữu ích. Hầu hết thời gian, một giải pháp có thể được tìm thấy bằng một ngôn ngữ khác có thể dễ dàng chuyển sang ngôn ngữ bạn chọn.

2

Loại tay cầm cửa sổ là chuỗi. Lý do cho điều đó là WinList trả về cả cửa sổ xử lý và tiêu đề cửa sổ. Một tiêu đề không thể phù hợp với một loại xử lý, nhưng một xử lý có thể phù hợp với một loại chuỗi (cho tiêu đề). Tôi đoán là họ đã lấy thiết kế đó và cũng áp dụng nó cho các chức năng khác. Nếu bạn nhìn vào tài liệu cho WinGetHandle nó sẽ cho bạn biết kiểu trả về cho một handle: Đó là một chuỗi.

AutoIt có chức năng có thể "chuyển đổi" số cơ sở 16 thành đối tượng HWND.

Chính xác! Đó là chìa khóa. AutoIt thực hiện điều này cho bạn. Bạn đang cố gắng chuyển đổi các xử lý thành một cái gì đó hữu ích cho AutoIt, nhưng AutoIt có thể đã sử dụng những xử lý được lưu trữ như chuỗi.

thử nghiệm của bạn nên là:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control") 
In: mainWindowTitle = "Untitled" 
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle) 
In: mainWindowHandle 
Out: u'000204AC' 
In: autoIt.WinGetTitle(mainWindowHandle) 
Out: u'Untitled - Notepad' 

Khi bạn muốn sử dụng tay cầm trong các thư viện khác, bạn có thể gặp một số vấn đề. Tôi khuyên bạn nên sau đó bạn thử phân tích cú pháp số như bạn đã làm trong các bài kiểm tra của mình và chuyển nó theo. AutoIt là 'thông minh' đủ để tìm ra những gì phải làm trong hầu hết các trường hợp, có thể thư viện không phải là mặc dù.

+0

Xin chào Manadar, cảm ơn phản hồi của bạn, nhưng nếu bạn nhìn vào ví dụ đầu tiên của tôi, bạn sẽ thấy rằng tôi đã thử chính xác những gì bạn đã đề cập. Nó phát ra chuỗi unicode như là cửa sổ xử lý, nhưng nó không thể trả về tiêu đề cửa sổ bằng cách sử dụng chuỗi unicode đó. Như tôi đã đề cập trong phần chỉnh sửa cuối cùng, tôi nghĩ rằng trong khi AutoIt có một hàm có thể chuyển đổi chuỗi unicode thành đối tượng HWND, AutoItX không làm cho hàm đó có sẵn thông qua dll COM, do đó các hàm có thể truy cập thông qua COM phải được gọi thông qua việc sử dụng các tiêu đề cửa sổ (bất kể chúng có thể xử lý nội bộ như thế nào). –