我如何使shell上下文菜单上的文件资源管理器来调整目录中的图像大小

本文关键字:调整 图像 文件 shell 何使 上下文 菜单 资源管理器 | 更新日期: 2023-09-27 18:05:43

我用的是windows 10。

它需要一些时间,直到我看到一个消息框说它已注册,不知道为什么它需要时间。之后什么都没有发生,我没有看到上下文菜单时,做鼠标右键单击在文件资源管理器。其中一个菜单是调整大小,当我点击它,选择它,它应该在程序中运行一个方法,将调整所有的图像在当前目录我在文件资源管理器。

但是,即使它在大约一年前就在windows 8上工作,调整大小的动作也花了很多时间,我不知道为什么。

这是Program.cs的代码:

using System;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
[assembly: CLSCompliant(true)]
namespace SimpleContextMenu
{
    static class Program
    {
        // file type to register
        const string FileType = "bitmapfile";//"jpegfile";
        // context menu name in the registry
        const string KeyName = "Simple Context Menu";
        const string KeyName1 = "Simple Context Menu1";
        // context menu text
        const string MenuText = "Copy to Grayscale";
        const string MenuText1 = "Resize all images";
        [STAThread]
        static void Main(string[] args)
        {
            System.Threading.Thread.Sleep(30000);
            // process register or unregister commands
            if (!ProcessCommand(args))
            {
                string action = args[0];
                MessageBox.Show(action);
                string fileName = args[1];
                if (action == "Copy")
                {
                    // invoked from shell, process the selected file
                    CopyGrayscaleImage(fileName);
                }
                else if (action == "Resize")
                {
                    string FilePath = Path.Combine(
                    Path.GetDirectoryName(fileName),
                    string.Format("{0} (resized){1}",
                    Path.GetFileNameWithoutExtension(fileName),
                    Path.GetExtension(fileName)));
                    MessageBox.Show(FilePath);
                    Bitmap bmp1 = new Bitmap(ResizeImages(FilePath, 100, 100));
                    bmp1.Save(FilePath);
                    bmp1.Dispose();
                }
            }
        }
        /// <summary>
        /// Process command line actions (register or unregister).
        /// </summary>
        /// <param name="args">Command line arguments.</param>
        /// <returns>True if processed an action in the command line.</returns>
        static bool ProcessCommand(string[] args)
        {
            // register
            if (args.Length == 0 || string.Compare(args[0], "-register", true) == 0)
            {
                // full path to self, %L is placeholder for selected file
                string menuCommand = string.Format("'"{0}'" Copy '"%L'"", Application.ExecutablePath);
                // register the context menu
                FileShellExtension.Register(Program.FileType,
                    Program.KeyName, Program.MenuText,
                    menuCommand);
                string menuCommand1 = string.Format("'"{0}'" Resize '"%L'"", Application.ExecutablePath);
                FileShellExtension.Register(Program.FileType,
                    Program.KeyName1, Program.MenuText1,
                    menuCommand1);
                MessageBox.Show(string.Format(
                    "The {0} shell extension was registered.",
                    Program.KeyName), Program.KeyName);
                return true;
            }
            // unregister       
            if (string.Compare(args[0], "-unregister", true) == 0)
            {
                // unregister the context menu
                FileShellExtension.Unregister(Program.FileType, Program.KeyName);
                MessageBox.Show(string.Format(
                    "The {0} shell extension was unregistered.",
                    Program.KeyName), Program.KeyName);
                return true;
            }
            // command line did not contain an action
            return false;
        }
        /// <summary>
        /// Make a grayscale copy of the image.
        /// </summary>
        /// <param name="filePath">Full path to the image to copy.</param>
        static void CopyGrayscaleImage(string filePath)
        {
            try
            {
                // full path to the grayscale copy
                string grayFilePath = Path.Combine(
                    Path.GetDirectoryName(filePath),
                    string.Format("{0} (grayscale){1}",
                    Path.GetFileNameWithoutExtension(filePath),
                    Path.GetExtension(filePath)));
                // using calls Dispose on the objects, important 
                // so the file is not locked when the app terminates
                using (Image image = new Bitmap(filePath))
                using (Bitmap grayImage = new Bitmap(image.Width, image.Height))
                using (Graphics g = Graphics.FromImage(grayImage))
                {
                    // setup grayscale matrix
                    ImageAttributes attr = new ImageAttributes();
                    attr.SetColorMatrix(new ColorMatrix(new float[][]{   
                        new float[]{0.3086F,0.3086F,0.3086F,0,0},
                        new float[]{0.6094F,0.6094F,0.6094F,0,0},
                        new float[]{0.082F,0.082F,0.082F,0,0},
                        new float[]{0,0,0,1,0,0},
                        new float[]{0,0,0,0,1,0},
                        new float[]{0,0,0,0,0,1}}));
                    // create the grayscale image
                    g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height),
                        0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attr);
                    // save to the file system
                    grayImage.Save(grayFilePath, ImageFormat.Jpeg);
                    // success
                    MessageBox.Show(string.Format("Copied grayscale image {0}", grayFilePath), Program.KeyName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("An error occurred: {0}", ex.Message), Program.KeyName);
                return;
            }
        }
        private static Bitmap ResizeImages(String filename, int maxWidth, int maxHeight)
        {
            using (Image originalImage = Image.FromFile(filename))
            {
                //Caluate new Size
                int newWidth = originalImage.Width;
                int newHeight = originalImage.Height;
                double aspectRatio = (double)originalImage.Width / (double)originalImage.Height;
                if (aspectRatio <= 1 && originalImage.Width > maxWidth)
                {
                    newWidth = maxWidth;
                    newHeight = (int)Math.Round(newWidth / aspectRatio);
                }
                else if (aspectRatio > 1 && originalImage.Height > maxHeight)
                {
                    newHeight = maxHeight;
                    newWidth = (int)Math.Round(newHeight * aspectRatio);
                }
                if (newWidth >= 0 && newHeight >= 0)
                {
                    Bitmap newImage = new Bitmap(newWidth, newHeight);
                    using (Graphics g = Graphics.FromImage(newImage))
                    {
                        //--Quality Settings Adjust to fit your application
                        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                        g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                        g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
                        return newImage;
                    }
                }
                return null;
            }
        }
    }
}

这是FileShellExtension.cs:

using System;
using System.Diagnostics;
using Microsoft.Win32;
namespace SimpleContextMenu
{
    /// <summary>
    /// Register and unregister simple shell context menus.
    /// </summary>
    static class FileShellExtension
    {
        /// <summary>
        /// Register a simple shell context menu.
        /// </summary>
        /// <param name="fileType">The file type to register.</param>
        /// <param name="shellKeyName">Name that appears in the registry.</param>
        /// <param name="menuText">Text that appears in the context menu.</param>
        /// <param name="menuCommand">Command line that is executed.</param>
        public static void Register(
            string fileType, string shellKeyName,
            string menuText, string menuCommand)
        {
            Debug.Assert(!string.IsNullOrEmpty(fileType) &&
                !string.IsNullOrEmpty(shellKeyName) &&
                !string.IsNullOrEmpty(menuText) &&
                !string.IsNullOrEmpty(menuCommand));
            // create full path to registry location
            string regPath = string.Format(@"{0}'shell'{1}", fileType, shellKeyName);
            // add context menu to the registry
            using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(regPath))
            {
                key.SetValue(null, menuText);
            }
            // add command that is invoked to the registry
            using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(
                string.Format(@"{0}'command", regPath)))
            {
                key.SetValue(null, menuCommand);
            }
        }
        /// <summary>
        /// Unregister a simple shell context menu.
        /// </summary>
        /// <param name="fileType">The file type to unregister.</param>
        /// <param name="shellKeyName">Name that was registered in the registry.</param>
        public static void Unregister(string fileType, string shellKeyName)
        {
            Debug.Assert(!string.IsNullOrEmpty(fileType) &&
                !string.IsNullOrEmpty(shellKeyName));
            // full path to the registry location           
            string regPath = string.Format(@"{0}'shell'{1}", fileType, shellKeyName);
            // remove context menu from the registry
            Registry.ClassesRoot.DeleteSubKeyTree(regPath);
        }
    }
}

我知道的标志是不使用/触摸注册表,但我试图找到一个简单的方法来调整一个目录中的图像的一些简单的接口给用户和唯一的方法来添加一个上下文菜单到文件资源管理器已经存在的菜单是通过注册到注册表。

我现在正在尝试使用sharpshel库,但不确定如何使用它:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using SharpShell.Attributes;
using SharpShellContextMenu;
using SharpShell.SharpContextMenu;
namespace SharpShellContextMenu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }

        [ComVisible(true)]
        [COMServerAssociation(AssociationType.ClassOfExtension, ".jpg")]
        public class CountLinesExtension : SharpContextMenu
        {
            protected override bool CanShowMenu()
            {
                return true;
            }
            protected override ContextMenuStrip CreateMenu()
            {
                //  Create the menu strip.
                var menu = new ContextMenuStrip();
                //  Create a 'count lines' item.
                var itemCountLines = new ToolStripMenuItem
                {
                    Text = "Resize Images",
                    //Image = Properties.Resources.CountLines
                };
                //  When we click, we'll count the lines.
                itemCountLines.Click += (sender, args) => CountLines();
                //  Add the item to the context menu.
                menu.Items.Add(itemCountLines);
                //  Return the menu.
                return menu;
            }
            private void CountLines()
            {
                // do the work
            }
        } 
    }
}

如何在构造函数中调用它

我如何使shell上下文菜单上的文件资源管理器来调整目录中的图像大小

为Windows资源管理器编写扩展是一项繁琐且容易出错的工作。SharpShell项目使。net开发人员可以轻松地集成到资源管理器中。看一看https://github.com/dwmkerr/sharpshell

为上下文菜单启用操作的方式如下(摘自本教程):

[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".txt")]
public class CountLinesExtension : SharpContextMenu
{        
    protected override bool CanShowMenu()
    {
        return true;
    }
    protected override ContextMenuStrip CreateMenu()
    {
        //  Create the menu strip.
        var menu = new ContextMenuStrip();
        //  Create a 'count lines' item.
        var itemCountLines = new ToolStripMenuItem
        {
            Text = "Count Lines...",
            Image = Properties.Resources.CountLines
        };
        //  When we click, we'll count the lines.
        itemCountLines.Click += (sender, args) => CountLines();
        //  Add the item to the context menu.
        menu.Items.Add(itemCountLines);
        //  Return the menu.
        return menu;
    }
    private void CountLines()
    {
        // do the work
    }
}