我该如何在C#中将字符串(例如“hello”)复制到系统剪贴板,这样下次按CTRL+V就可以获得“hello”呢?
有两个类存在于不同的程序集和命名空间中。
WinForms:使用以下命名空间声明,确保 Main
标记为带有 [STAThread]
属性:
using System.Windows.Forms;
WPF: 使用以下命名空间声明
using System.Windows;
控制台:添加对System.Windows.Forms
的引用,使用以下命名空间声明,确保将 Main
标记为带有[STAThread]
属性。另一个答案中提供了逐步指南。
using System.Windows.Forms;
要复制完全相同的字符串(在这种情况下是字面量):
Clipboard.SetText("Hello, clipboard");
要复制文本框的内容,请使用TextBox.Copy()或先获取文本,然后设置剪贴板值:
Clipboard.SetText(txtClipboard.Text);
点击此处查看示例。 或者... 官方MSDN文档 或者 这里的WPF。
备注:
剪贴板是桌面UI概念,在服务器端代码中尝试设置它(如ASP.Net)只会在服务器上设置值,对用户在浏览器中看到的内容没有影响。虽然链接答案允许使用SetApartmentState
在服务器端运行剪贴板访问代码,但这不太可能是您想要实现的目标。
如果按照此问题中的信息后代码仍然出现异常,请参见在复制字符串到剪贴板时出现“当前线程必须设置为单线程公寓 (STA)”错误
此问题/答案涵盖常规.NET,有关.NET Core,请参见-.Net Core-复制到剪贴板?
为了以逐步方式创建控制台项目,您首先需要添加System.Windows.Forms
引用。以下步骤适用于使用.NET 4.5的Visual Studio Community 2013:
System.Windows.Forms
。接下来,在代码顶部与其他using
语句一起添加以下语句:
using System.Windows.Forms;
然后,将以下任一Clipboard
。SetText
语句添加到您的代码中:
Clipboard.SetText("hello");
// OR
Clipboard.SetText(helloString);
最后,将 Main
方法添加 STAThreadAttribute
,以避免出现 System.Threading.ThreadStateException
。[STAThreadAttribute]
static void Main(string[] args)
{
// ...
}
StackOverflowException
类紧随STAThreadAttribute
之后。=) - nikodaemus使用 WPF C# 复制到剪贴板时遇到 System.Threading.ThreadStateException
,以下是我的经验,并附上了可以在所有浏览器中正常工作的代码:
Thread thread = new Thread(() => Clipboard.SetText("String to be copied to clipboard"));
thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
thread.Start();
thread.Join();
感谢这里的帖子提供的帮助。
但是这只在本地主机上有效,所以不要在服务器上尝试,因为它不会起作用。
在服务器端,我使用了zeroclipboard
来实现。这是经过大量研究找到的唯一方法。
Clipboard.SetText("hello");
你需要使用 System.Windows.Forms
或者 System.Windows
命名空间。
Clip.exe是Windows中用于设置剪贴板的可执行文件。注意,它不适用于除Windows以外的其他操作系统,这仍然很糟糕。
/// <summary>
/// Sets clipboard to value.
/// </summary>
/// <param name="value">String to set the clipboard to.</param>
public static void SetClipboard(string value)
{
if (value == null)
throw new ArgumentNullException("Attempt to set clipboard with null");
Process clipboardExecutable = new Process();
clipboardExecutable.StartInfo = new ProcessStartInfo // Creates the process
{
RedirectStandardInput = true,
FileName = @"clip",
};
clipboardExecutable.Start();
clipboardExecutable.StandardInput.Write(value); // CLIP uses STDIN as input.
// When we are done writing all the string, close it so clip doesn't wait and get stuck
clipboardExecutable.StandardInput.Close();
return;
}
UseShellExecute = false
到ProcessStartInfo
中后,这个方法对我起作用了,就像文档https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.redirectstandardinput?view=net-7.0#remarks中所写的那样。 - undefinedProcessStartInfo.StandardInputEncoding
设置为System.Text.Encoding
Unicode。除非您使用较旧的.NET版本,否则请在Process.StandardInput.BaseStream
周围创建自己的StreamWriter
,并使用Write
和Close
它,请参阅:https://stackoverflow.com/a/50001438/1997873。 - undefinedClipboard.SetDataObject(object sthhere)
:Clipboard.SetDataObject("Yay! No more STA thread!");
这适用于 .net core,无需引用 System.Windows.Forms
using Windows.ApplicationModel.DataTransfer;
DataPackage package = new DataPackage();
package.SetText("text to copy");
Clipboard.SetContent(package);
它支持跨平台。在Windows上,您可以按下windows + V查看剪贴板历史记录。
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
</appSettings>
Clipboard.SetText(CreateDescription());
如果您不想或无法使用System.Windows.Forms,您可以使用Windows本地API:user32和剪贴板函数GetClipboardData
和SetClipboardDat
(pinvoke)
可以在这里找到.NET 6包装库https://github.com/MrM40/WitWinClipboard/tree/main
await Clipboard.Default.SetTextAsync("This text was highlighted in the UI.");
,并且应该引用Microsoft.Maui.Essentials.dll
。详细的解答在this article中有详细介绍。