Skip to content

Instantly share code, notes, and snippets.

@sancarn
Last active June 27, 2018 09:36
Show Gist options
  • Save sancarn/a6bbfddffe8b86439dbe15a5d471f0b4 to your computer and use it in GitHub Desktop.
Save sancarn/a6bbfddffe8b86439dbe15a5d471f0b4 to your computer and use it in GitHub Desktop.

Ruby IDispatch

A way of dispatching Ruby classes and objects as COM OLE objects, via win32ole.

Uses

Useful for IE intergration:

require 'win32ole'
require_relative 'RubyIDispatch.rb'

#Instantiate IE
ie = WIN32OLE.new('InternetExplorer.Application')
ie.navigate("about:blank")
sleep(0.1) until !ie.busy
  
#Write HTML including setVar() function to install BHO.
html = <<Heredoc
<html>
  <head>
    <script>
      window.Ruby = {}
      document.setVar = function(name,val){
        window.Ruby[name]=val;
      }
    </script>
  </head>
  <body>
    <h1>Hello!</h1>
  </body>
</html>
Heredoc
ie.document.write(html)
ie.visible = true

#Create OLE class for File object:
OLEFile = WIN32OLE::getDispatch(File)

#Create BHO:
ie.document.setVar("File",OLEFile)

After calling the above script, RubyFile can now be accessed directly from JavaScript!

f = Ruby.File.new("my/cool/file")
console.log(f.read())
f.puts("some data")
f.close

// Also access to singleton methods
Ruby.File.write("my/other/file","Some cool Ruby function")

To Do

  • Add class wrapper. E.G. WIN32OLE::getDispatch(File)
  • Add pure method wrapper. E.G. WIN32OLE::getDispatch(method(:someMethod))
  • Add object wrapper. E.G. WIN32OLE::getDispatch(someObject)
  • Wrap returned objects from other ruby functions.
  • Wrap blocks so they are callable from JavaScript as callback functions.
require 'win32ole'
# Required methods for WIN32OLE dispatch objects
module WIN32OLE::IDispatch
def call
nil
end
def value(*args)
nil
end
end
# Wrapper for sending classes over COM via WIN32OLE
def WIN32OLE::getClassDispatch(klass)
Class.new(klass) do
include WIN32OLE::IDispatch
extend WIN32OLE::IDispatch
end
end
#Warning methods which return other objects, will not return IDispatch wrapped objects. In the future, proxy objects will be used here.
require_relative 'RubyIDispatch.rb'
#Create OLE class for File object:
OLEFile = WIN32OLE::getDispatch(File)
#----------------------------------------------------------
#Pass to IE:
IE.document.setVar("File",OLEFile)
#----------------------------------------------------------
#Extend a class and create dispatch:
class FileExtension < File
def something
end
def self.somethingElse
end
end
OLEFileExtension = WIN32OLE::getDispatch(FileExtension)
#----------------------------------------------------------
#Extend a class and create dispatch (alternative):
OLEFileExtension_ = WIN32OLE::getDispatch(Class.new(File) do
def something
end
def self.somethingElse
end
end)
#----------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment