lib/win32/autogui/application.rb in win32-autogui-0.2.1 vs lib/win32/autogui/application.rb in win32-autogui-0.3.0

- old
+ new

@@ -38,11 +38,12 @@ # class Calculator < Autogui::Application # # def initialize(options = {}) # defaults = { # :name => "calc", - # :title => "Calculator" + # :title => "Calculator", + # :logger_logfile => 'log/calc.log' # } # super defaults.merge(options) # end # # def edit_window @@ -63,10 +64,11 @@ # class Application include Windows::Process include Windows::Synchronize include Windows::Handle + include Autogui::Logging # @return [String] the executable name of the application attr_accessor :name # @return [String] the executable application parameters @@ -87,37 +89,62 @@ # @return [Number] the wait timeout in seconds used by Process.create attr_accessor :create_process_timeout # @example initialize an application on the path # - # Application.new :name => "calc" + # app = Application.new :name => "calc" # + # @example initialize with relative DOS path + # + # app = Application.new :name => "binaries\\mybinary.exe" + # # @example initialize with full DOS path # - # Application.new :name => "\\windows\\system32\\calc.exe" + # app = Application.new :name => "\\windows\\system32\\calc.exe" # + # @example initialize with logging to file at the default WARN level (STDOUT logging is the default) + # + # app = Application.new :name => "calc", :logger_logfile => 'log/calc.log' + # + # @example initialize with logging to file at DEBUG level + # + # include Autogui::Logging + # app = Application.new :name => "calc", :logger_logfile => 'log/calc.log', :logger.level => Log4r::DEBUG + # + # @example initialize without logging to file and turn it on later + # + # include Autogui::Logging + # app = Application.new :name => "calc" + # logger.logfile = 'app.log' + # # @param [Hash] options initialize options # @option options [String] :name a valid win32 exe name with optional path # @option options [String] :title the application window title, used along with the pid to locate the application main window, defaults to :name # @option options [Number] :parameters command line parameters used by Process.create # @option options [Number] :create_process_timeout (10) timeout in seconds to wait for the create_process to return # @option options [Number] :main_window_timeout (10) timeout in seconds to wait for main_window to appear + # @option options [String] :logger_logfile (nil) initialize Log4r::Logger's output filename + # @option options [String] :logger_level (Log4r::WARN) initialize Log4r::Logger's initial level # def initialize(options = {}) unless options.kind_of?(Hash) - raise ArgumentError, 'Initialize expecting options to be a Hash' + raise_error ArgumentError, 'Initialize expecting options to be a Hash' end @name = options[:name] || name @title = options[:title] || name @main_window_timeout = options[:main_window_timeout] || 10 @create_process_timeout = options[:create_process_timeout] || 10 @parameters = options[:parameters] + # logger setup + logger.logfile = options[:logger_logfile] if options[:logger_logfile] + logger.level = options[:logger_level] if options[:logger_level] + # sanity checks - raise 'Application name not set' unless name + raise_error 'application name not set' unless name start end # Start up the binary application via Process.create and @@ -149,12 +176,12 @@ # done with the handles CloseHandle(process_handle) CloseHandle(thread_handle) - raise "Start command failed on create_process_timeout" if ret == WAIT_TIMEOUT - raise "Start command failed while waiting for idle input, reason unknown" unless (ret == 0) + raise_error "start command failed on create_process_timeout" if ret == WAIT_TIMEOUT + raise_error "start command failed while waiting for idle input, reason unknown" unless (ret == 0) @pid end # The application main window found by enumerating windows # by title and application pid. This method will keep looking @@ -166,22 +193,26 @@ # @see initialize for options # def main_window return @main_window if @main_window + # pre sanity checks + raise_error "calling main_window without a pid, application not initialized properly" unless @pid + raise_error "calling main_window without a window title, application not initialized properly" unless @title + timeout(main_window_timeout) do begin # There may be multiple instances, use title and pid to id our main window @main_window = Autogui::EnumerateDesktopWindows.new.find do |w| w.title.match(title) && w.pid == pid end sleep 0.1 end until @main_window end - # sanity checks - raise "cannot find main_window, check application title" unless @main_window + # post sanity checks + raise_error "cannot find main_window, check application title" unless @main_window @main_window end # Call the main_window's close method @@ -241,10 +272,33 @@ # def clipboard @clipboard || Autogui::Clipboard.new end - private + private + + # @overload raise_error(exception, message) + # raise and log specific exception with message + # @param [Exception] to raise + # @param [String] message error message to raise + # + # @overload raise_error(message) + # raise and log generic exception with message + # @param [String] message error message to raise + # + def raise_error(*args) + if args.first.kind_of?(Exception) + exception_type = args.shift + error_message = args.shift || 'Unknown error' + else + raise ArgumentError unless args.first.is_a?(String) + exception_type = RuntimeError + error_message = args.shift || 'Unknown error' + end + + logger.error error_message + raise exception_type, error_message + end end end