Windows资源管理器上下文菜单单击功能不起作用

时间:2014-03-15 20:04:51

标签: c# .net wpf contextmenu

我想让用户只选择以下扩展文件:.jpg,.png, .tiff, .gif, .png。使用Windows Explorer Context Menu我按照以下链接:http://www.codeproject.com/Articles/15171/Simple-shell-context-menu?msg=4779433#xx4779433xx我可以注册并取消注册成功获取.jpg文件。

当我点击命令fileCopytoDirA时,没有发生任何事情,即功能无效。 (我使用控制台应用程序使用相同的方法,我的功能正常工作)。

哪里&如何在fileCopytoDirA点击期间调用该功能?有什么帮助吗?

![在此处输入图片说明] [1]

在注册管理机构注册的代码:

InitializeComponent();
string menuCommand = string.Format("\"{0}\" \"%L\"", Application.Current);
FileShellExtension.Register("OISjpegfile", "fileCopytoDirA", "fileCopytoDirA", menuCommand);

点击期间要执行的功能:

 static void fileCopytoDirA(string filePath)
     { 
        try
            {          
                File.Copy(filePath, System.IO.Path.Combine(@"C:\Test\Directories\", System.IO.Path.GetFileName(filePath)), true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("An error occurred: {0}", ex.Message));
                return;
            }
       }

Function to un register the registry entries during WPF application close:

     private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {

                FileShellExtension.Unregister("OISjpegfile", "fileCopytoDirA");
            }


  [1]: http://i.stack.imgur.com/eAN5F.png

Metadings回答后编辑:

 App()
        {
            InitializeComponent();
            string menuCommand = string.Format("\"{0}\" \"%L\"", System.Reflection.Assembly.GetExecutingAssembly().Location);
            FileShellExtension.Register("OISjpegfile", "fileCopytoDirA", "fileCopytoDirA", menuCommand);
        }

        [STAThread]
        public static void Main(string args)
        {

            if (string.IsNullOrEmpty(args))
            {
                // Run your Main Form
                // (blocks until Form1 is closed)
                Window3 window = new Window3();
                App app = new App();
                app.Run(window);
            }
            else
            {
                // Run the context menu action
                fileCopytoDirA(args);
            }

            // exit
        }

        static void fileCopytoDirA(string args)
        {
            try
            {

                File.Copy(args, System.IO.Path.Combine(@"C:\Test\Directories\", System.IO.Path.GetFileName(args)), true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("An error occurred: {0}", ex.Message));
                return;
            }
        }

1 个答案:

答案 0 :(得分:2)

(简单)注册表设置是您的应用程序由参数执行,因为它将在控制台中调用:

app.exe "TheJpegFile.jpg"

因此,切入点为static void Main(string args),您可以在此处调用fileCopytoDirA(args)。资源管理器没有神奇的方式通过其名称调用函数。您可以implement the COM interfaces, as for example this project does,或者通过重定向您的Main来快速而肮脏地进行;如果没有参数,运行(windows窗体)应用程序 - 如果有参数,请执行操作并退出:

using System;
using System.Windows.Forms;

public static class Program {

    public static void Main(string args) {

        if (string.IsNullOrEmpty(args)) {
            // Run your Main Form
            // (blocks until Form1 is closed)
            Application.Run(new Form1());
        }
        else {
            // Run the context menu action
            fileCopytoDirA(args);
        }

        // exit
    }

}

FileShellExtension.Register函数定义为

public static void Register(string fileType,
       string shellKeyName, string menuText, string menuCommand)

所以参数是

  1. string fileType - 文件扩展名的HKC注册表项
  2. string shellKeyName - 只是用于区分外壳扩展的资源管理器的注册表项名称
  3. string menuText - 用户可以在资源管理器的上下文菜单中看到的内容
  4. string menuCommand - shell命令资源管理器就像在控制台或链接中执行一样

  5. P.S:在WPF中它类似,但你创建了新的YourApp类(派生自System.Windows.Application),然后调用Run。

    假设Application.xaml看起来像

    <Application x:Class="WpfApplication1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
    </Application>
    

    并且您的应用程序类位于名为WpfApplication1的名称空间App中,并且您有一个Window1.xaml,q&#39; n&#39; d看起来像

    namespace WpfApplication1
    {
        public partial class App : Application
        {
            App()
            {
                InitializeComponent();
            }
    
            [STAThread]
            static void Main(string args)
            {
    
                if (string.IsNullOrEmpty(args)) {
                    // Run your Main Form
                    // (blocks until Form1 is closed)
                    Window1 window = new Window1();
                    App app = new App();
                    app.Run(window);
                }
                else {
                    // Run the context menu action
                    fileCopytoDirA(args);
                }
    
                // exit
            }
    
            static void fileCopytoDirA(string args) {
                // this your part ;)
            }
        }
    }
    

    顺便说一下。我从this source获取了WPF主要部分,从Application.xaml中删除StartupURI="Window1.xaml"属性似乎很重要,现在它看起来像

    <Application x:Class="WpfApplication1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    </Application>