Копировать в буфер обмена в Ruby, HTML или C#

Как скопировать текст в буфер обмена в Ruby?

Звучит просто, верно? Но я пытаюсь сделать это уже 5 дней, но безуспешно.

Я искал в Интернете, но все, что я нашел, это то, как это сделать в более новых версиях Ruby (я использую 1.8.7, и я не могу использовать более новую версию).

Поэтому я попытался сделать файл HTML, чтобы сделать это за меня. Попробовав 4-5 разных способов (из онлайн-руководств), в 3 браузерах и даже просмотрев исходный код Photobucket, чтобы попытаться понять, как он копирует коды img, я сдался. У меня ничего не получалось.

Поэтому я создал C# .exe и заставил свою программу на Ruby вызывать его. Наконец что-то отправляется в буфер обмена. Это шаг вперед, но все же это только первое слово в строке. Когда я пытаюсь скопировать two words, копируется только two.

моя программа Ruby выглядит так:

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

а в С# (в CopyClip) это так:

Clipboard.set_text(args[0])

По сути, меня не волнует, поможете ли вы мне сделать это на Ruby, HTML, C# или любом другом языке, главное, чтобы он работал.


person yasmin    schedule 09.10.2013    source источник
comment
Использует ли ваш код С# строковые аргументы из Main? В основном, аргументы командной строки? Если в аргументах есть пробел, он будет рассматривать каждый элемент с интервалом как отдельный аргумент.   -  person gunr2171    schedule 09.10.2013
comment
Вы знаете, как использовать драгоценные камни? Если да, это может вам помочь: github.com/janlelis/clipboard (это вторая ссылка в google и выглядит очень хорошо) и в c# нет необходимости   -  person FLCL    schedule 09.10.2013


Ответы (5)


Этот ответ отлично подходит для OSX:

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

def pbpaste
 `pbpaste`
end
person Roman B.    schedule 17.04.2014
comment
Использование clip вместо pbcopy работает для копирования в буфер обмена в Windows - person Michiel; 02.02.2017
comment
Это замечательно. Я предлагаю всем добавить их в свои ~/.irb.rb (они должны быть в блоке class << self; ... end) - person Alexander; 11.06.2021

Я подозреваю, что если вы заключите аргумент своего приложения C# в кавычки, вы получите весь текст в args[0]:

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

В качестве альтернативы и, возможно, лучше, если ваш текст содержит апострофы или другие специальные символы оболочки:

system("CopyClip.exe", text)

Или, может быть, даже лучше, используйте гем буфера обмена - у меня это работает на 1.8.7, но я не не удалось протестировать его в Windows:

require 'clipboard'
Clipboard.copy text
person Jakob S    schedule 09.10.2013
comment
Я думаю, что аргументы команды С#/команды ищут значения, которые должны быть заключены в двойные кавычки. - person gunr2171; 09.10.2013

Драгоценный камень буфера обмена позволяет вам получить доступ к буферу обмена в Liunx, 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 все работает нормально.

person Vitalii    schedule 31.03.2014

Для тех, кто пишет приложения GTK+ (которые не являются OP), запись в буфер обмена довольно проста:

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

Вы также можете использовать первичный (Gdk::Selection::PRIMARY) или вторичный (Gdk::Selection::SECONDARY) выбор X.

См. также полный ruby API и лежащий в его основе C API.

person starfry    schedule 09.03.2017

Похоже, вы используете Windows, это работает с Ruby 1.9.3 под Windows 7.

Исходный ответ см. в разделе 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

В моей коллекции был еще один скрипт, который работал в 32-битной Windows 7, если у вас возникли проблемы с первым и вы используете только 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

Если вы не против установить гем, вот гораздо более простое решение, работает на 64-битной Windows7, 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
person peter    schedule 19.12.2015