C# 在Windows(资源管理器)中单击粘贴时执行应用程序

C# 在Windows(资源管理器)中单击粘贴时执行应用程序,c#,C#,我有一个应用程序,基本上是一台复印机,但它可以做更多的其他事情。我无法克服的是: 我想在用户选择几个文件(在资源管理器、桌面或Windows中的任何位置)时打开应用程序,所有这些选定的文件都应该在缓存中或类似的地方,以便它位于列表或其他地方 这是由Windows完成的,所以我不必这样做。当用户选择并复制了他想要选择的所有文件时,当用户将这些文件粘贴到其他地方时,我如何执行应用程序?让它自动打开 我有这个: [DllImport("User32.dll")] protected static ex

我有一个应用程序,基本上是一台复印机,但它可以做更多的其他事情。我无法克服的是:

我想在用户选择几个文件(在资源管理器、桌面或Windows中的任何位置)时打开应用程序,所有这些选定的文件都应该在缓存中或类似的地方,以便它位于列表或其他地方

这是由Windows完成的,所以我不必这样做。当用户选择并复制了他想要选择的所有文件时,当用户将这些文件粘贴到其他地方时,我如何执行应用程序?让它自动打开

我有这个:

[DllImport("User32.dll")]
protected static extern int
SetClipboardViewer(int hWndNewViewer);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool
ChangeClipboardChain(IntPtr hWndRemove,
IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg,
IntPtr wParam,
IntPtr lParam);

IntPtr nextClipboardViewer;


protected override void WndProc(ref System.Windows.Forms.Message m)
{
    // Defined in winuser.h
    const int WM_DRAWCLIPBOARD = 0x308;
    const int WM_CHANGECBCHAIN = 0x030D;

    switch (m.Msg)
    {
        case WM_DRAWCLIPBOARD:
            DisplayClipboardData();
            SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
            break;

        case WM_CHANGECBCHAIN:
            if (m.WParam == nextClipboardViewer)
            {
                nextClipboardViewer = m.LParam;
            }
            else
            {
                SendMessage(nextClipboardViewer, m.Msg, m.WParam,
                m.LParam);
            }
            break;

        default:
            base.WndProc(ref m);
            break;
    }
}

void DisplayClipboardData()
{
    try
    {
        IDataObject iData = new DataObject();
        iData = Clipboard.GetDataObject();
        if (iData.GetDataPresent(DataFormats.Rtf))
        {
            richTextBox1.Rtf = (string)iData.GetData(DataFormats.Rtf);
        }
        else if (iData.GetDataPresent(DataFormats.Text))
        {
            richTextBox1.Text = (string)iData.GetData(DataFormats.Text);
        }
        else
        {
            richTextBox1.Text = "[Clipboard data is not RTF or ASCII Text]";
        }


    }
    catch (Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

但这仅在选中文本时有效。如何显示每个文件的文件目录?

如果您希望对复制(Ctrl+C)或剪切(Ctrl+V)操作而不是粘贴(Ctrl+V)操作做出反应,那么它实际上相对简单。
你所要做的就是监视剪贴板,因为这就是这些信息的来源。您必须侦听的数据格式是
FileDrop

不幸的是,您将不得不使用WinAPI来侦听剪贴板更改

收到此类更改后,您可以检索复制的文件列表,如下所示:

void DisplayClipboardData()
{
    if(!Clipboard.ContainsFileDropList())
        return;

    var fileList = Clipboard.GetFileDropList();
    // Do something with the file list.
}

我认为你必须做两件事:

1) 在winform应用程序中使用连接到windows键盘和鼠标事件

2) 做你需要的事

这种方法的主要特点是,监听键盘事件的钩子必须与线程相关联,因此应用程序必须已经加载,并且在接收事件时保持驻留在内存中。您可以创建一个有限的gui,并拥有一个


编辑:在windows挂钩上

用户在粘贴(CTRL+V)之前,必须先剪切(CTRL+X)或复制(CTRL+C)。您确定要对粘贴而不是剪切或复制做出反应吗?那么哪一种效果最好?那两种方法都可以。因此,如果用户复制,那么所有这些文件目录都应该在应用程序的列表中。贝比7:正如我所说,你需要检查FileDrop。您当前正在检查Rtf和文本。将
DisplayClipboardData
更改为仅检查
DataFormats.FileDrop
。噢!对不起,这是我的错。塔克斯!我现在已经启动并运行了:)。如何在文件列表中找到文件的文件大小?例如,使用
FileInfo
class:So FileInfo FileInfo=newfileinfo(filename);