Reputation: 102935
Is there a way you can copy to clipboard in Node.js? Any modules or ideas what so ever? I'm using Node.js on a desktop application. Hopefully that clears up why I want it to be able to achieve this.
Upvotes: 174
Views: 129489
Reputation: 63477
Check out clipboardy
. It lets you copy/paste cross-platform. It is more actively maintained than the copy-paste
module mentioned in another answer and it fixes many of that module's issues.
import clipboardy from 'clipboardy';
// Copy
clipboardy.writeSync('🦄');
// Paste
clipboardy.readSync();
//🦄
Upvotes: 133
Reputation: 11
If you'd like to copy a file (not its contents) to the clipboard, consider the following:
For macOS:
let filePath; // absolute path of the file you'd like to copy
require('child_process').exec(
`osascript -e 'set the clipboard to POSIX file "${filePath}"'`,
function (err, stdout, stderr) {
console.log(stdout); // to confirm the application has been run
}
);
For Windows:
const filePath; // absolute path of the file you'd like to copy
// Make a temporary folder
const tmpFolder = path.join(__dirname, `tmp-${Date.now()}`);
fs.mkdirSync(tmpFolder, { recursive: true });
// Copy the file into the temporary folder
const tmpFilePath = path.join(tmpFolder, path.basename(filePath));
fs.copyFileSync(filePath, tmpFilePath);
// To copy the contents of the folder in PowerShell,
// you need to add a wildcard to the end of the path
const powershellFolder = path.join(tmpFolder, '*');
require('child_process').exec(
`Set-Clipboard -PATH "${powershellFolder}"`, { 'shell': 'powershell.exe' },
function (err, stdout, stderr) {
console.log(stdout); // to confirm the application has been run
}
);
Upvotes: 1
Reputation: 2465
This is how you would do this on node-ffi for windows, this interacts directly with the native clipboard API from windows. (Which means you can also read/write different clipboard formats)
var {
winapi,
user32,
kernel32,
constants
} = require('@kreijstal/winffiapi')
const GMEM_MOVEABLE=0x2;
var stringbuffer=Buffer.from("hello world"+'\0');//You need a null terminating string because C api.
var hmem=kernel32.GlobalAlloc(GMEM_MOVEABLE,stringbuffer.length);
var lptstr = kernel32.GlobalLock(hmem);
stringbuffer.copy(winapi.ref.reinterpret(lptstr, stringbuffer.length));
kernel32.GlobalUnlock(hmem);
if (!user32.OpenClipboard(0)){
kernel32.GlobalLock(hmem);
kernel32.GlobalFree(hmem);
kernel32.GlobalUnlock(hmem);
throw new Error("couldn't open clipboard");
}
user32.EmptyClipboard();
user32.SetClipboardData(constants.clipboardFormats.CF_TEXT, hmem);
user32.CloseClipboard();
Upvotes: 1
Reputation: 111
I saw there wasn't a solution here or anywhere obvious that worked for Windows, so reposting this one found in the depths of page 2 on Google search, which uses the Windows native command line clip
, and avoids any potentially messy usage of command line workarounds such as echo foo | clip
like suggested above.
var cp = require("child_process");
var child = cp.spawn('clip');
child.stdin.write(result.join("\n"));
child.stdin.end();
Hope this helps someone!
Upvotes: 3
Reputation: 2236
Shortest way in Windows:
const util = require('util');
require('child_process').spawn('clip').stdin.end(util.inspect('content_for_the_clipboard'));
Upvotes: 42
Reputation: 14725
For OS X:
function pbcopy(data) {
var proc = require('child_process').spawn('pbcopy');
proc.stdin.write(data); proc.stdin.end();
}
write()
can take a buffer or a string. The default encoding for a string will be utf-8.
Upvotes: 181
Reputation: 20459
Here's a module that provide copy
and paste
functions: https://github.com/xavi-/node-copy-paste
When require("copy-paste").global()
is executed, two global functions are added:
> copy("hello") // Asynchronously adds "hello" to clipbroad
> Copy complete
> paste() // Synchronously returns clipboard contents
'hello'
Like many of the other answer mentioned, to copy and paste in node you need to call out to an external program. In the case of node-copy-paste
, it calls out to pbcopy/pbpaste
(for OSX), xclip
(for linux), and clip
(for windows).
This module was very helpful when I was doing a lot of work in the REPL for a side project. Needless to say, copy-paste
is only a command line utility -- it is not meant for server work.
Upvotes: 40
Reputation: 14602
A clipboard is not inherent to an operating system. It's a construct of whatever window system the operating system happens to be running. So if you wanted this to work on X for example, you would need bindings to Xlib and/or XCB. Xlib bindings for node actually exist: https://github.com/mixu/nwm. Although I'm not sure whether it gives you access to the X clipboard, you might end up writing your own. You'll need separate bindings for windows.
edit: If you want to do something hacky, you could also use xclip:
var exec = require('child_process').exec;
var getClipboard = function(func) {
exec('/usr/bin/xclip -o -selection clipboard', function(err, stdout, stderr) {
if (err || stderr) return func(err || new Error(stderr));
func(null, stdout);
});
};
getClipboard(function(err, text) {
if (err) throw err;
console.log(text);
});
Upvotes: 26
Reputation: 7239
Mac has a native command line pbcopy
for this usecase:
require('child_process').exec(
'echo "test foo bar" | pbcopy',
function(err, stdout, stderr) {
console.log(stdout); // to confirm the application has been run
}
);
Same code for Linux but replace pbcopy
with Xclip (apt get install xclip
)
Upvotes: 5
Reputation: 154948
I managed to do so by creating a different application which handles this. It's certainly not the best way, but it works.
I'm on Windows and created a VB.NET application:
Module Module1
Sub Main()
Dim text = My.Application.CommandLineArgs(0)
My.Computer.Clipboard.SetText(text)
Console.Write(text) ' will appear on stdout
End Sub
End Module
Then in Node.js, I used child_process.exec
to run the VB.NET application, with the data to be copied passed as a command line argument:
require('child_process').exec(
"CopyToClipboard.exe \"test foo bar\"",
function(err, stdout, stderr) {
console.log(stdout); // to confirm the application has been run
}
);
Upvotes: 4