是否有更简单的方法使用Windows ctrl+;C#控制台应用程序中的v(粘贴)功能?
我已经构建了一个具有命令解释器的控制台应用程序。为了让事情变得更简单,我需要添加在按下ctrl+v时读取剪贴板的支持。当我按ctrl+v时,我在控制台中看到符号^v,因此我将用剪贴板文本替换该字符。通过谷歌搜索,我发现System.Windows.Forms.clipboard.GetText()可以访问剪贴板 我的问题是:是否有更好的解决方案向控制台应用程序添加剪贴板支持?可能不使用System.Windows.Forms.Clipboard?也许一个互操作调用就可以做到这一点? 此解决方案的缺点之一是剪贴板仅在线程定义为[StatThread]时工作。如果我能去掉^V符号也会更好 这是当前解决方案的代码:是否有更简单的方法使用Windows ctrl+;C#控制台应用程序中的v(粘贴)功能?,c#,.net,windows,c#-2.0,console-application,C#,.net,Windows,C# 2.0,Console Application,我已经构建了一个具有命令解释器的控制台应用程序。为了让事情变得更简单,我需要添加在按下ctrl+v时读取剪贴板的支持。当我按ctrl+v时,我在控制台中看到符号^v,因此我将用剪贴板文本替换该字符。通过谷歌搜索,我发现System.Windows.Forms.clipboard.GetText()可以访问剪贴板 我的问题是:是否有更好的解决方案向控制台应用程序添加剪贴板支持?可能不使用System.Windows.Forms.Clipboard?也许一个互操作调用就可以做到这一点? 此解决方案的
using System;
using System.Threading;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program
{
public static readonly string ClipboardChar = Convert.ToChar(22).ToString();
[STAThread]
static void Main(string[] args)
{
Console.Write("Do some pastin': ");
//read
Console.ForegroundColor = ConsoleColor.White;
string result = Console.ReadLine();
Console.ResetColor();
//read keyboard
if (result.Contains(ClipboardChar))
{
result = result.Replace(ClipboardChar, Clipboard.GetText());
}
//write result
Console.WriteLine("\nResult: ");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(result);
Console.ResetColor();
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
}
}
如果单击console应用程序窗口左上角的图标,您将获得一个“编辑”|“粘贴”选项。您当然可以使用p/Invoke来完成此操作。请将示例代码视为概念证明,因为它是快速拼凑和测试的。我有一些自由-例如我的
GlobalLock
原型返回string
,尽管WinAPI确实返回LPVOID
using System;
using System.Runtime.InteropServices;
namespace clipboard
{
class Program
{
public static void Main(string[] args)
{
ConsoleKeyInfo ki = Console.ReadKey( true );
if( ( ki.Key == ConsoleKey.V ) && ( ki.Modifiers == ConsoleModifiers.Control ) )
{
Console.WriteLine( "Ctrl+V pressed" );
string s = ClipBoard.PasteTextFromClipboard();
Console.WriteLine( s );
}
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
class ClipBoard
{
[DllImport("user32.dll", SetLastError = true)]
private static extern Int32 IsClipboardFormatAvailable( uint format );
[DllImport("user32.dll", SetLastError = true)]
private static extern Int32 OpenClipboard( IntPtr hWndNewOwner );
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetClipboardData( uint uFormat );
[DllImport("user32.dll", SetLastError = true)]
private static extern Int32 CloseClipboard();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern Int32 GlobalLock( IntPtr hMem );
[DllImport("kernel32.dll", SetLastError = true)]
private static extern Int32 GlobalUnlock( IntPtr hMem );
[DllImport("kernel32.dll")]
public static extern UIntPtr GlobalSize(IntPtr hMem);
const uint CF_TEXT = 1;
public static string PasteTextFromClipboard()
{
string result = "";
if( IsClipboardFormatAvailable( CF_TEXT ) == 0 )
{
return result;
}
if( OpenClipboard((IntPtr)0) == 0 )
{
return result;
}
IntPtr hglb = GetClipboardData(CF_TEXT);
if( hglb != (IntPtr)0 )
{
UIntPtr size = GlobalSize(hglb);
IntPtr s = GlobalLock(hglb);
byte[] buffer = new byte[(int)size];
Marshal.Copy(s, buffer, 0, (int)size);
if (s != null)
{
result = ASCIIEncoding.ASCII.GetString(buffer);
GlobalUnlock(hglb);
}
}
CloseClipboard();
return result;
}
}
}
为什么?您不想引用System.Windows.Forms吗?它是一个标准的.NET库,所以部署时应用程序不会变大。如果您使用任何其他方法,应用程序的启动速度都会变慢,会变慢吗?我为这个问题添加了当前解决方案的一些缺点:此解决方案的缺点之一是剪贴板仅在线程定义为[StatThread]时工作。如果我能去掉^V符号也会好得多。另一方面,你可能会发现这些关于通过.NET扩展控制台api的文章很有用:,@VinayC谢谢你。很高兴能读点书!哈哈哈。。。是的,但我的用户希望通过ctlr+v获得支持,这太简单了,正是我所需要的。谢谢:)我想,
Alt+Space,E,P
应该比点击角落图标更快。看起来不错。。。但是现在我需要研究如何用ReadKey()模拟ReadLine():dt这个P/Invoke还去掉了System.Windows.Forms.Clipboard需要的[STAThread]:我爱你,男人。非常聪明有效。为了提高效率,我扔掉了表格,我真的很讨厌再次注射的想法。Thanx@Mika雅各比-没问题。实际上,社区编辑已经清理了我的原始代码,所以我关于“获取自由”的评论不再适用!