在Ruby、HTML或C#中复制到剪贴板

22

如何在Ruby中复制文本到剪贴板?

听起来很简单吧?但我已经尝试了5天,却没有成功。

我在互联网上搜索,但所有的结果都是关于新版本Ruby的(我正在使用1.8.7版本,并且不能使用更高版本)。

所以我尝试创建一个HTML文件来实现它。在尝试了4-5种不同的方法(从在线指南中学习),在3个浏览器中进行测试,甚至查看Photobucket的源代码来尝试弄清楚它如何复制img代码后,我放弃了。对我来说,没有任何方法可以实现。

于是我制作了一个C# .exe并让我的Ruby程序调用它。最终传递到剪贴板的只有第一个单词,这只是一步向前。当我尝试复制two words时,只有two被复制。

我的Ruby程序看起来像这样:

system  ("CopyClip.exe #{text}")

在C#中(在CopyClip中),它会执行以下操作:

Clipboard.set_text(args[0])

基本上,我不在乎你用Ruby、HTML、C#或任何其他语言来帮助我完成它,只要它能正常工作。


你的C#代码是否使用了Main方法中的字符串参数?基本上是指命令行参数吗?如果参数中有空格,它会将每个带空格的项视为不同的参数。 - gunr2171
你知道如何使用gems吗?如果是的话,这个链接可能会对你有所帮助:https://github.com/janlelis/clipboard(这是谷歌搜索结果中的第二个链接,看起来非常好)。而且在C#中也没有必要。 - FLCL
5个回答

57

这个答案 在OSX上效果很棒:

def pbcopy(input)
 str = input.to_s
 IO.popen('pbcopy', 'w') { |f| f << str }
 str
end

def pbpaste
 `pbpaste`
end

3
在Windows系统中,使用clip命令代替pbcopy命令可以将内容复制到剪贴板。 - Michiel
这太棒了。我建议每个人都将它们添加到他们的~/.irb.rb文件中(它们必须在class << self; ... end块中)。 - Alexander

6

Clipboard gem允许您在Linux,MacOS和Windows上访问剪贴板。重点是简单文本。您可以使用Clipboard.copy("string")复制字符串,并使用Clipboard.paste()进行粘贴。
基本上就是这样。

现在让我们更详细地看一下具体的平台。

  • Linux 要支持Linux,请需要xclip小工具。您可以在Ubuntu上使用sudo apt-get install xclip安装它。
    此外,您可以选择从哪个剪贴板粘贴(默认为PRIMARYCLIPBOARD)。 copy()会将其复制到所有剪贴板中Clipboard::CLIPBOARDS,例如Clipboard.paste :primary

  • macOS
    在macOS上,它可以正常工作。


6

我怀疑如果你在调用C#应用程序时将参数用引号括起来,你将会获得args[0]中的所有文本:

system("CopyClip.exe '#{text}'")

或者,如果您的文本包含撇号或其他特殊的 shell 字符,则可能更好:

system("CopyClip.exe", text)

或者更好的方法是使用clipboard gem - 在1.8.7上这对我有效,但我无法在Windows上进行测试:

require 'clipboard'
Clipboard.copy text

我认为c# / 命令参数正在寻找需要用双引号包装的值。 - gunr2171

2

对于那些编写GTK+应用程序(OP不是其中之一)的人来说,将内容写入剪贴板非常简单:

Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD).set_text(content).store 

您还可以使用主要的 (Gdk::Selection::PRIMARY) 或次要的 (Gdk::Selection::SECONDARY) X 选择。

另请参阅完整的 Ruby API 和其基础的 C API


0

看起来你正在使用Windows,在Windows 7下可以使用Ruby 1.9.3。

有关原始答案,请参见{{link1:Ruby使用Fiddle复制到剪贴板}}

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

在我的收藏中有另一个脚本,在Windows 7 32位上曾经可以使用,如果您在使用第一个脚本时遇到问题,并且只使用32位,请尝试使用这个。
#!/usr/bin/env ruby -w
# win32 only

require 'singleton'
require 'thread'
require 'Win32API'

class Clipboard
  include Singleton

  CF_TEXT = 1

  def initialize
    @@mutex = Mutex.new
    @@open = Win32API.new("user32","OpenClipboard",['L'],'L')
    @@close = Win32API.new("user32","CloseClipboard",[],'L')
    @@empty = Win32API.new("user32","EmptyClipboard",[],'L')
    @@set = Win32API.new("user32","SetClipboardData",['L','P'],'L')
    @@get = Win32API.new("user32", "GetClipboardData", ['L'], 'L')
    @@lock = Win32API.new("kernel32", "GlobalLock", ['L'], 'P')
    @@unlock = Win32API.new("kernel32", "GlobalUnlock", ['L'], 'L')
  end

  def copy
    @@mutex.synchronize do
      @@open.Call(0)
      str = @@lock.Call(@@get.Call(CF_TEXT))
      @@unlock.Call(@@get.Call(CF_TEXT))
      @@close.Call
      return str
    end
  end

  def paste(str)
    @@mutex.synchronize do
      @@open.Call(0)
      @@empty.Call
      @@set.Call(CF_TEXT, str)
      @@close.Call
      @@lock = Win32API.new("kernel32", "GlobalLock", ['L'], 'P')
      @@unlock = Win32API.new("kernel32", "GlobalUnlock", ['L'], 'L')
      return nil
    end
  end
end

clip = Clipboard.instance
puts clip.copy
puts str
clip.paste("foo")
puts clip.copy

如果您不介意安装一个 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接