有没有更简单的方法在C#控制台应用程序中使用Windows ctrl + v(粘贴)功能?

Kee*_*ker 4 .net c# windows console-application c#-2.0

我已经构建了一个具有命令解释器的控制台应用程序.为了方便起见,我需要在按下ctrl + v时添加对阅读剪贴板的支持.当我按ctrl + v时,我在控制台中看到符号^ V,所以我用剪贴板文本替换该字符.经过一些谷歌搜索后,我发现System.Windows.Forms.Clipboard.GetText()可以访问剪贴板.

我的问题是:是否有更好的解决方案为控制台应用程序添加剪贴板支持?可能没有使用System.Windows.Forms.Clipboard?也许互操作可以做到这一点?

此解决方案的一个缺点是剪贴板仅在线程定义为[STAThread]时才起作用.如果我能摆脱^ V符号,它也会更好.

这是当前解决方案的代码:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*-UK 9

你当然可以使用P/Invoke来做到这一点.请将示例代码视为概念验证,因为它已快速拼凑在一起并经过测试.我已经采取了一些自由 - 例如我的GlobalLock返回原型,string尽管Win API确实返回了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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)