有没有更简单的方法在C#控制台应用程序中使用Windows ctrl + v(粘贴)功能?
我已经构建了一个带有命令解释器的控制台应用程序。为了使事情变得更容易,我需要增加在按下 ctrl + v 时阅读剪贴板的支持。当我按ctrl + v时,我会在控制台中看到符号 ^ V ,因此我用剪贴板文本替换了该字符。经过一番谷歌搜索后,我发现System.Windows.Forms.Clipboard.GetText()可以访问剪贴板。
I’ve build a console application that has a command interpreter. To make things easier I needed to add support for reading the clipboard when ctrl+v is pressed. When I press ctrl+v I see the symbol ^V in the console, so I’m replacing that character with the clipboard text. After some googling I’ve found out that the clipboard can be accessed by System.Windows.Forms.Clipboard.GetText().
我的问题是:是否有更好的解决方案将剪贴板支持添加到控制台应用程序?可能不使用System.Windows.Forms.Clipboard?
此解决方案的缺点之一是剪贴板仅在将线程定义为[STAThread]时才起作用。如果我可以摆脱^ V符号,那就更好了。
One of the drawbacks of this solution is that the clipboard only works when the thread is defined as [STAThread]. It would also be a lot nicer if I could get rid of the ^V symbol.
这是当前解决方案的代码:
This is the code of the current solution:
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();
}
}
}
您当然可以使用P / Invoke来执行此操作。由于示例代码被迅速拼凑在一起,因此请将其视为概念验证。经过测试。我采取了一些*措施-例如,我的 GlobalLock
原型返回 string
,尽管Win API确实返回了 LPVOID
。
You can certainly use P/Invoke to do this. Please treat the sample code as proof-of-concept as it was rapidly cobbled together & tested. I've taken a few liberties - for instance my prototype for GlobalLock
returns string
although the Win API really returns 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;
}
}
}