Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有更简单的方法使用Windows ctrl+;C#控制台应用程序中的v(粘贴)功能?_C#_.net_Windows_C# 2.0_Console Application - Fatal编程技术网

是否有更简单的方法使用Windows ctrl+;C#控制台应用程序中的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?也许一个互操作调用就可以做到这一点? 此解决方案的

我已经构建了一个具有命令解释器的控制台应用程序。为了让事情变得更简单,我需要添加在按下ctrl+v时读取剪贴板的支持。当我按ctrl+v时,我在控制台中看到符号^v,因此我将用剪贴板文本替换该字符。通过谷歌搜索,我发现System.Windows.Forms.clipboard.GetText()可以访问剪贴板

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

此解决方案的缺点之一是剪贴板仅在线程定义为[StatThread]时工作。如果我能去掉^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();
        }
    }
}

如果单击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雅各比-没问题。实际上,社区编辑已经清理了我的原始代码,所以我关于“获取自由”的评论不再适用!