открыть программу один раз с несколькими файлами в качестве аргументов из проводника - PullRequest
3 голосов
/ 24 апреля 2010

У меня есть программа, которая работает, когда файл открывается с помощью меню правой кнопки мыши в проводнике. Но если я выбираю несколько файлов, а затем щелкаю правой кнопкой мыши и открываю с моей программой, тогда она открывает несколько экземпляров моей программы, а не просто передает несколько файлов в качестве аргументов одному экземпляру. Программа написана на vb.net, но не является формой Windows, это просто модуль, поэтому я могу отметить опцию Single instance в свойствах Visual Studio.

Итак, как мне открыть несколько файлов из контекстного меню проводника в одном экземпляре.

Ответы [ 3 ]

6 голосов
/ 24 апреля 2010

Здесь нет счастливых ответов, Windows Explorer не предоставляет простой способ запустить вашу программу, передавая все выбранные файлы. Для этого требуется обработчик контекстного меню оболочки , их очень сложно написать в управляемом коде. И до .NET 4.0 нельзя было писать безопасно.

Тем не менее его легко смоделировать с помощью инфраструктуры приложений, доступной в VB.NET, сделать ваше приложение одиночным и реализовать событие StartupNextInstance . Единственная проблема заключается в том, что это не особенно быстро. И это не работает в приложениях консольного режима.

1 голос
/ 17 марта 2015

эта ссылка помогла мне получить пути к выбранным файлам в проводнике, нажав на элемент контекстного меню: .NET Shell Extensions - контекстные меню оболочки

это на языке C #, но, как сказал автор статьи, его можно использовать и на vb.net.

очень просто:)

Надеюсь, это поможет и вам! :)

Вот Шаги:

1) Загрузите библиотеку SharpShell >>

Загрузите zip-файл «Библиотека SharpShell» в верхней части статьи и добавьте ссылку на загруженный файл SharpShell.dll.

или вы можете скачать его через Nuget:

Если у вас установлен Nuget, просто выполните быстрый поиск SharpShell и установите его напрямую - или получите сведения о пакете по адресу https://www.nuget.org/packages/SharpShell.

Добавить следующие ссылки:

System.Windows.Forms
System.Drawing

Используйте их в верхней части вашего кода:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpShell;
using SharpShell.SharpContextMenu;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using SharpShell.Attributes;

Получите ваш класс от SharpContextMenu Щелкните правой кнопкой мыши часть SharpContextMenu и выберите Implement Abstract Class.

CanShowMenu

Эта функция вызывается, чтобы определить, следует ли показывать расширение контекстного меню для данного набора файлов. Файлы, выбранные пользователем, находятся в свойстве SelectedItemPaths. Мы можем проверить эти пути к файлам, чтобы увидеть, действительно ли мы хотим показать меню. Если должно отображаться меню, верните true. Если нет, верните false.

CreateMenu

Эта функция вызывается для фактического создания контекстного меню. Стандартные WinForms ContextMenuStrip - это все, что нам нужно вернуть.

Вот все пространство имен SourceCode:

namespace CountLinesExtension
{
[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".txt")]
public class Class1 : SharpContextMenu
{
protected override bool CanShowMenu()
{
        //  We will always show the menu.
        return true;
        //throw new NotImplementedException();
    }

    protected override ContextMenuStrip CreateMenu()
    {
        //  Create the menu strip.
        var menu = new ContextMenuStrip();

        //  Create a 'count lines' item.
        var itemCountLines = new ToolStripMenuItem
        {
            Text = "Count Lines"
        };

        //  When we click, we'll call the 'CountLines' function.
        itemCountLines.Click += (sender, args) => CountLines();

        //  Add the item to the context menu.
        menu.Items.Add(itemCountLines);

        //  Return the menu.
        return menu;
        //throw new NotImplementedException();
    }
    private void CountLines()
    {
        //  Builder for the output.
        var builder = new StringBuilder();

        //  Go through each file.
        foreach (var filePath in SelectedItemPaths)
        {
            //  Count the lines.
            builder.AppendLine(string.Format("{0} - {1} Lines",
              Path.GetFileName(filePath), File.ReadAllLines(filePath).Length));
        }

        //  Show the ouput.
        MessageBox.Show(builder.ToString());
    } 

}
}

Далее мы должны дать сборке строгое имя. Есть способы обойти это требование, но, как правило, это лучший подход. Для этого щелкните правой кнопкой мыши проект и выберите «Свойства». Затем перейдите к «Подписание». Выберите «Подписать сборку», укажите «Новый» для ключа и выберите имя ключа. Вы можете защитить паролем ключ, если хотите, но это не обязательно

Теперь установите и зарегистрируйте расширение Shell: Инструмент регазм

Вы можете использовать инструмент 'regasm' для установки и регистрации расширения оболочки. При использовании regasm расширение оболочки будет установлено в реестр (т. Е. Идентификатор класса COM-сервера будет помещен в раздел «Классы COM-сервера» и связан с путем к файлу фактического сервера), оно также зарегистрирует ассоциации.

Средство управления сервером

Инструмент диспетчера сервера - мой предпочтительный подход для установки / удаления и регистрации / отмены регистрации, по крайней мере, во время разработки, поскольку он позволяет устанавливать и регистрировать как отдельные шаги. Это также позволит вам указать, устанавливаете ли вы / удаляете и т. Д. В 32-битном или 64-битном режиме.

Это был весь исходный код Sample. мы можем добавить любое количество элементов контекстного меню, любую функцию, любое расширение файла и т. д.

0 голосов
/ 19 октября 2012

Хотя я знаю, что это было для vb.net, я уверен, что вы можете использовать этот код на c # с несколькими изменениями, но это сработало для меня. Возможно, это не лучший способ сделать это, но для меня это был самый простой способ. Он проверяет, запущен ли заголовок приложения перед запуском второй копии.

Это в Program.cs

 static frmMain Form;

    [STAThread]
    static void Main(string[] args)
    {
        bool blnCurrentlyRunning = false;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Process[] processes = Process.GetProcesses();
        foreach (var item in processes)
        {
            if (item.MainWindowTitle.IndexOf("Application Title") != -1)
                blnCurrentlyRunning = true;
        }

        if (!blnCurrentlyRunning)
        {
            Form = new frmMain();
            Application.Run(Form);
        }
        else
        {
            Application.Exit();
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...