#!ruby =begin Markdown * cygwin の ruby 1.8.4 では enumWindows で確実に SEGV する。 * mswin32 版を使えば大丈夫 =end require "dl/import" module User32 WM_KEYDOWN = 0x0100 WM_KEYUP = 0x0101 VK_F5 = 0x0074 CHAR_MAX = 512 LIB = DL.dlopen("user32") def get_window_title(hwnd) buff = "\0" * CHAR_MAX getWindowText = LIB["GetWindowText", "ILSI"] r, rs = getWindowText.call(hwnd ,buff , CHAR_MAX) return buff.delete("\0") end module_function :get_window_title def find_window(wclass, title) findWindow = LIB["FindWindow", "LPP"] r, rs = findWindow.call(wclass, title) r end module_function :find_window def post_message(hwnd, p1, p2, l) postMessage = LIB["PostMessage", "ILLLL"] r, rs = postMessage.call(hwnd, p1, p2, l) r end module_function :post_message def set_foreground_window(hwnd) setForegroundWindow = LIB["SetForegroundWindow", "IL"] r, rs = setForegroundWindow.call(hwnd) r end module_function :set_foreground_window def window_visible?(hwnd) isWindowVisible = LIB["IsWindowVisible", "IL"] r, rs = isWindowVisible.call(hwnd) (r == 0) ? false : true end module_function :window_visible? def enum_windows(enum_windows_proc) enumWindows = LIB["EnumWindows", "IPL"] r, rs = enumWindows.call(enum_windows_proc, 0) end module_function :enum_windows end # 何度もコールバックを生成するとすぐにエラーで落ちる。 # そのため、ここで一度だけ作るように call_back = DL.callback("ILL") do |hwnd, lparam| if User32.window_visible?(hwnd) title = User32.get_window_title(hwnd) if title =~ /(Microsoft Internet Explorer|Opera)$/ User32.set_foreground_window(hwnd) sleep 0.05 User32.post_message(hwnd, User32::WM_KEYDOWN, User32::VK_F5, 0) User32.post_message(hwnd, User32::WM_KEYUP, User32::VK_F5, 0) end end 1 end require "yaml" require "webrick" require "net/http" require "pp" $stdout.sync = true begin @config = YAML.load_file("reload-config.yaml") rescue Errno::ENOENT @config = { "server" => { } } end pp @config server_config = { :Port => 4321, :Logger => WEBrick::Log.new(nil, 0), :AccessLog => WEBrick::Log.new(nil, 0), }.update(@config["server"]) mount_path = @config["mount-path"] || "/reload" puts "Port: #{server_config[:Port]}" puts "Path: #{mount_path}" require "pathname" srv = WEBrick::HTTPServer.new(server_config) srv.mount_proc(mount_path) do |req, res| system(Pathname.pwd + 'reload_firefox.exe') User32.enum_windows(call_back) res.content_type = "text/plain" res.body = "reloaded" @config["chain"].each do |uri| Thread.start(uri) do |uri| begin puts "Chaining `#{uri}'" uri = URI(uri) Net::HTTP.get(uri) rescue Exception => e puts "Error on chaining `#{uri}'" puts e.message end end end end trap (:INT) { srv.shutdown } srv.start