用Fiddle将Ruby复制到剪贴板

我试图用Fiddle模块将字符串复制到剪贴板,但此代码失败。

require'fiddle'; user32 = Fiddle.dlopen 'USER32.dll'; $openClipboard = Fiddle::Function.new(user32['OpenClipboard'],[Fiddle::TYPE_INT],Fiddle::TYPE_INT); $closeClipboard = Fiddle::Function.new(user32['CloseClipboard'],[],Fiddle::TYPE_INT); $emptyClipboard = Fiddle::Function.new(user32['EmptyClipboard'],[],Fiddle::TYPE_INT); $setClipboardData = Fiddle::Function.new(user32['SetClipboardData'],[Fiddle::TYPE_INT,Fiddle::TYPE_VOIDP],Fiddle::TYPE_VOIDP); class Clipboard def initialize @closed = false; puts "openClipboard : #{$openClipboard.call(0)}"; puts "emptyClipboard : #{$emptyClipboard.call}"; end def data=(d) return 'Cannot write to closed clipboard' if @closed; puts "setClipboardData : #{$setClipboardData.call(1,d)}"; # 1 is CF_TEXT end def close return 'Already closed' if @closed; @closed = true; puts "closeClipboard : #{$closeClipboard.call}"; end end c = Clipboard.new puts 'going to write'; gets; c.data = 'red'; # Should write 'red' to the clipboard p 'after writing to the clipboard'; gets; c.close; p 'closed'; gets 

但它在#data =方法中失败了。 (这只是尝试翻译http://www.codeproject.com/Articles/2242/Using-the-Clipboard-Part-I-Transferring-Simple-Tex中的代码)。 如何在不使用外部gem /库的情况下做任何想法?

因为Ruby 1.9.3不支持dlopen方法,所以无法帮助你。 在我的脚本库中,我找到了这个工作示例。 在https://github.com/janlelis/clipboard/blob/master/lib/clipboard/windows.rb找到它

在我的gem列表中找不到open3,所以我认为它是标准库的一部分。 无论如何,要在这样的级别与操作系统进行交互,你需要某种gem,无论是否合并,小提琴也是一种gem。

 require 'open3' module Clipboard; end module Clipboard::Windows extend self CF_TEXT = 1 CF_UNICODETEXT = 13 GMEM_MOVEABLE = 2 # get ffi function handlers begin require 'ffi' rescue LoadError raise LoadError, 'Could not load the required ffi gem, install it with: gem install ffi' end module User32 extend FFI::Library ffi_lib "user32" ffi_convention :stdcall attach_function :open, :OpenClipboard, [ :long ], :long attach_function :close, :CloseClipboard, [ ], :long attach_function :empty, :EmptyClipboard, [ ], :long attach_function :get, :GetClipboardData, [ :long ], :long attach_function :set, :SetClipboardData, [ :long, :long ], :long end module Kernel32 extend FFI::Library ffi_lib 'kernel32' ffi_convention :stdcall attach_function :lock, :GlobalLock, [ :long ], :pointer attach_function :unlock, :GlobalUnlock, [ :long ], :long attach_function :size, :GlobalSize, [ :long ], :long attach_function :alloc, :GlobalAlloc, [ :long, :long ], :long end # see http://www.codeproject.com/KB/clipboard/archerclipboard1.aspx def paste(_ = nil) ret = "" if 0 != User32.open( 0 ) hclip = User32.get( CF_UNICODETEXT ) if hclip && 0 != hclip pointer_to_data = Kernel32.lock( hclip ) data = "" # Windows Unicode is ended by to null bytes, so get the whole string size = Kernel32.size( hclip ) data << pointer_to_data.get_bytes( 0, size - 2 ) if RUBY_VERSION >= '1.9' ret = data.force_encoding("UTF-16LE").encode(Encoding.default_external) # TODO catch bad encodings else # 1.8: fallback to simple CP850 encoding require 'iconv' utf8 = Iconv.iconv( "UTF-8", "UTF-16LE", data)[0] ret = Iconv.iconv( "CP850", "UTF-8", utf8)[0] end if data && 0 != data Kernel32.unlock( hclip ) end end User32.close( ) end ret || "" end def clear if 0 != User32.open( 0 ) User32.empty( ) User32.close( ) end paste end def copy(data_to_copy) if ( RUBY_VERSION >= '1.9' ) && 0 != User32.open( 0 ) User32.empty( ) data = data_to_copy.encode("UTF-16LE") # TODO catch bad encodings data << 0 handler = Kernel32.alloc( GMEM_MOVEABLE, data.bytesize ) pointer_to_data = Kernel32.lock( handler ) pointer_to_data.put_bytes( 0, data, 0, data.bytesize ) Kernel32.unlock( handler ) User32.set( CF_UNICODETEXT, handler ) User32.close( ) else # don't touch anything Open3.popen3( 'clip' ){ |input,_,_| input << data_to_copy } # depends on clip (available by default since Vista) end paste end end Clipboard::Windows.copy("test") puts Clipboard::Windows.paste 

如果您不介意安装gem,这里有一个更简单的解决方案,适用于Windows7 64位,Ruby 1.9.3。

 #gem install clipboard require 'clipboard' Clipboard.copy("This is a sentence that has been copied to your clipboard") puts Clipboard.paste