简体   繁体   English

用Ruby,HTML或C#复制到剪贴板

[英]Copy to Clipboard in Ruby, HTML or C#

How do you copy text to the clipboard in Ruby? 如何在Ruby中将文本复制到剪贴板?

Sounds simple right? 听起来很简单吧? But I've been trying to do this for 5 days now, with no success. 但是我现在已经尝试了5天,没有成功。

I searched on internet, but all I got is how to do it in newer versions of Ruby (I'm using 1.8.7 and no I can't use a newer version). 我在互联网上搜索,但我得到的是如何在较新版本的Ruby中做到这一点(我使用的是1.8.7而且我不能使用更新的版本)。

So I tried making a HTML file to do it for me. 所以我尝试制作一个HTML文件来为我做。 After trying 4-5 different ways (from online guides), in 3 browsers, and even looking at Photobucket's source code to try figuring how it copies img codes, I gave up. 尝试了4-5种不同的方式(来自在线指南),在3个浏览器中,甚至查看Photobucket的源代码,试图找出它如何复制img代码,我放弃了。 Nothing worked for me. 没有什么对我有用。

So I made a C# .exe and made my Ruby program call it. 所以我创建了一个C#.exe并让我的Ruby程序调用它。 Finally something is being sent to the clipboard. 最后有些东西被发送到剪贴板。 It's a step forward, but still, it's only the first word in a string. 这是向前迈出的一步,但它仍然只是字符串中的第一个单词。 When I try copying two words , only two is copied. 当我尝试复制two words ,只有two被复制。

my Ruby program looks like this: 我的Ruby程序看起来像这样:

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

and in C# (in CopyClip), it does: 在C#中(在CopyClip中),它确实:

Clipboard.set_text(args[0])

Basically, I don't care if you help me do it in Ruby, HTML, C#, or any other language, as long as it works. 基本上,我不在乎你是否帮助我用Ruby,HTML,C#或任何其他语言来做,只要它有效。

This answer works great for OSX: 这个答案适用于OSX:

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

def pbpaste
 `pbpaste`
end

The clipboard gem allows you to access the clipboard on Liunx, MacOS and Windows. 剪贴板gem允许您访问Liunx,MacOS和Windows上的剪贴板。 The focus is on simple text. 重点是简单的文字。 You can copy a string with Clipboard.copy("string") and paste it with Clipboard.paste() . 您可以复制与Clipboard.copy一个字符串(“字符串”),并将其与粘贴Clipboard.paste()
That's it, basically. 就是这样,基本上。

Now let's take a closer look at the specific platforms. 现在让我们仔细看看具体的平台。

  • Linux For Linux support, the little utility xclip is needed. Linux For Linux支持,需要小实用程序xclip。 You can install it on Ubuntu with sudo apt-get install xclip . 您可以使用sudo apt-get install xclip在Ubuntu上安装它。
    Furthermore, you can choose from which clipboard you want to paste (the default is PRIMARYCLIPBOARD). 此外,您可以选择要粘贴的剪贴板(默认为PRIMARYCLIPBOARD)。 copy() copies to all the clipboards in Clipboard::CLIPBOARDS , fo example Clipboard.paste :primary . copy()复制到Clipboard::CLIPBOARDS所有剪贴板,例如Clipboard.paste :primary

  • macOS 苹果系统
    On the macOS, it works fine. 在macOS上,它工作正常。

I suspect if you wrap the argument to your C# app in quotes, you'll get all the text in args[0] : 我怀疑如果你用引号将参数包装到你的C#应用​​程序中,你将获得args[0]所有文本:

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

Alternatively, and probably better in case your text contains apostrophes or other special shell characters: 或者,如果您的文本包含撇号或其他特殊shell字符,可能会更好:

system("CopyClip.exe", text)

Or perhaps even better, use the clipboard gem - this works for me on 1.8.7, but I haven't been able to test it on Windows: 或者甚至更好,使用剪贴板gem - 这在1.8.7上适用于我,但我无法在Windows上测试它:

require 'clipboard'
Clipboard.copy text

For those writing GTK+ applications (which the OP isn't), writing to the clipboard is quite straightforward: 对于那些编写GTK +应用程序(OP不是)的人来说,写入剪贴板非常简单:

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

You can also use the primary ( Gdk::Selection::PRIMARY ) or secondary ( Gdk::Selection::SECONDARY ) X selections. 您还可以使用主要( Gdk::Selection::PRIMARY )或辅助( Gdk::Selection::SECONDARY )X选择。

See also the full ruby API and its underlying C API . 另请参阅完整的ruby API及其底层C API

Seems like you are using windows, this works with Ruby 1.9.3 under windows 7. 好像你正在使用Windows,这适用于Windows 7下的Ruby 1.9.3。

For the original answer, see Ruby copy to clipboard with Fiddle 对于原始答案,请参阅使用Fiddle将Ruby复制到剪贴板

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

In my collection I had another script that used to work in Windows 7 32 bit, if you have trouble with the first one and only use 32 bit, try this one 在我的收藏中,我有另一个脚本,曾经在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

If you don't mind to install a gem, here is a much simpler solution, works on windows7 64 bit, Ruby 1.9.3. 如果您不介意安装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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM