简体   繁体   English

枚举文件夹/子文件夹内容,右键单击C#中系统托盘应用程序的上下文菜单

[英]Enumerate folder/subfolder contents to right-click context menu of system tray application in C#

I'm utilizing the template from https://alanbondo.wordpress.com/2008/06/22/creating-a-system-tray-app-with-c/ for creating a system tray icon that has a right-click context menu. 我正在使用https://alanbondo.wordpress.com/2008/06/22/creating-a-system-tray-app-with-c/中的模板来创建具有右键单击上下文的系统任务栏图标菜单。

I'm able to have one of the buttons launch an explorer process that opens to the root of a directory using this function 我可以使用其中一个按钮启动一个资源管理器进程,该进程使用此函数打开目录的根目录

    private void MyApps(object sender, EventArgs e)
    {
        String currentUser = Environment.UserName.ToString();
        Process explorer = new Process();
        explorer.StartInfo.FileName = "explorer.exe";
        explorer.StartInfo.Arguments = @"C:\Users\" + currentUser + @"\desktop\MyApps";
        explorer.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
        explorer.Start();
    }

What I would rather do is have the system tray icon button, when clicked, expand into a sub-menu that contains the contents of the desired directory, which itself contains browseable sub-folders. 我宁愿做的是系统托盘图标按钮,当单击时,展开到一个子菜单,其中包含所需目录的内容,该目录本身包含可浏览的子文件夹。 Imagine the (pre-Windows 8) Start menu with nested menus and applications; 想象一下带有嵌套菜单和应用程序的(Windows 8之前的)“开始”菜单; that is the behavior I'd like to mimic. 这就是我想模仿的行为。

What I have found thus far are multiple projects people have written to create their own customized Windows Explorer shell, do actually have to go that far in order to dynamically enumerate the contents of the desired folder into the right-click context menu of a system tray icon? 到目前为止,我发现人们已经编写了多个项目来创建自己的自定义Windows资源管理器外壳,实际上必须走的很远,以便将所需文件夹的内容动态枚举到系统任务栏的右键单击上下文菜单中图标?

I'm much more comfortable using visual studio forms for .NET applications but from what I have read, there's no way to actually 'hide' the form at launch, so for now I'm using C# 我对使用.NET应用程序的Visual Studio表单感到更加自在,但据我所读,目前还没有办法在启动时真正“隐藏”该表单,所以现在我正在使用C#

Any advice or suggestions would be appreciated. 任何意见或建议,将不胜感激。 Thanks! 谢谢!

Edit: Here's the updated code with the suggested method for recursively populating the menu item with the contents of the specified directory. 编辑:这是更新的代码,其中包含建议的方法,用于使用指定目录的内容递归填充菜单项。 I'm now getting an error that "System.Windows.Forms.MenuItem" does not contain a definition for DropDownItems 我现在收到一个错误,“System.Windows.Forms.MenuItem”不包含DropDownItems的定义

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;



namespace MyTrayApp
{
    public class SysTrayApp : Form
    {
        [STAThread]
        public static void Main()
        {
            Application.Run(new SysTrayApp());
        }

        private NotifyIcon trayIcon;
        private ContextMenu trayMenu;

        public SysTrayApp()
        {
            trayMenu = new ContextMenu();
            trayMenu.MenuItems.Add("Exit", OnExit);
            trayMenu.MenuItems.Add("My Applications").Click += new EventHandler(MyApps);

            trayIcon = new NotifyIcon();
            trayIcon.Text = "MyTrayApp";
            trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40);

            trayIcon.ContextMenu = trayMenu;
            trayIcon.Visible = true;
        }

        protected override void OnLoad(EventArgs e)
        {
            Visible = false; // Hide form window.
            ShowInTaskbar = false; // Remove from taskbar.

            base.OnLoad(e);
        }

        private void OnExit(object sender, EventArgs e)
        {
            Application.Exit();
        }

        protected override void Dispose(bool isDisposing)
        {
            if (isDisposing)
            {
                trayIcon.Dispose();
            }

            base.Dispose(isDisposing);
        }

        private void MyApps(object sender, EventArgs e)
        {
            String currentUser = Environment.UserName.ToString();

            string[] directories = Directory.GetDirectories(@"C:\Users\" + currentUser + @"\desktop\My Applications");
            foreach (string dir in directories)
            {
                string[] subdir = Directory.GetDirectories(dir);
                this.trayMenu.MenuItems.Add(dir);
                foreach (string sub in subdir)
                {
                    (trayMenu.MenuItems[trayMenu.MenuItems.Count - 1] as MenuItem).DropDownItems.Add(sub); 


                }

                string[] files = Directory.GetFiles(dir);
                foreach (string file in files)
                {
                    this.trayMenu.MenuItems.Add(file);
                }
            }
        }


    }
}

This is a simple quick test i've made, using a simple ContextMenuStrip. 这是我使用一个简单的ContextMenuStrip做的简单快速测试。 It of course should be recursive, but just to get you on the track: 它当然应该是递归的,但是只是为了让您步入正轨:

string[] directories = Directory.GetDirectories(@"D:\descargas");
foreach (string dir in directories)
{
     string[] subdir = Directory.GetDirectories(dir);
     this.contextMenuStrip1.Items.Add(dir);
     foreach(string sub in subdir)
     {
          (contextMenuStrip1.Items[contextMenuStrip1.Items.Count-1] as ToolStripMenuItem).DropDownItems.Add(sub);
     }

     string[] files = Directory.GetFiles(dir);
     foreach(string file in files)
     {
          this.contextMenuStrip1.Items.Add(file);
     }
}

Edit 编辑

As you are using ContextMenu, and using your provided code, you should do something like this: 在使用ContextMenu并使用提供的代码时,应执行以下操作:

private void MyApps(object sender, EventArgs e)
    {
        String currentUser = Environment.UserName.ToString();

        string[] directories = Directory.GetDirectories(@"C:\Users\" + currentUser + @"\desktop\My Applications");
        foreach (string dir in directories)
        {
            string[] subdir = Directory.GetDirectories(dir);
            MenuItem mi=new MenuItem(dir);
            foreach (string sub in subdir)
            {
                mi.MenuItems.Add(sub); 


            }


            string[] files = Directory.GetFiles(dir);
            foreach (string file in files)
            {
                mi.MenuItems.Add(file);
            }
            this.trayMenu.MenuItems.Add(mi);
        }
    }

I haven't tested it, but I think this would do more or less what you want 我还没有测试过,但是我认为这或多或少会达到您想要的效果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM