открыть программу один раз с несколькими файлами в качестве аргументов из проводника

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

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


person Jonathan.    schedule 24.04.2010    source источник


Ответы (3)


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

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

person Hans Passant    schedule 24.04.2010

эта ссылка помогла мне получить пути к выбранным файлам в проводнике, щелкнув элемент контекстного меню: Расширения оболочки .NET — Контекстные меню оболочки

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

реально легко :)

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

Вот шаги:

1) Скачайте библиотеку SharpShell>>

Загрузите zip-файл «SharpShell Library» вверху статьи и добавьте ссылку на загруженный файл 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.

СоздатьМеню

Эта функция вызывается для фактического создания контекстного меню. Стандартный 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());
    } 

}
}

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

Теперь установите и зарегистрируйте расширение оболочки: инструмент regasm

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

Инструмент диспетчера серверов

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

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

person ACE    schedule 17.03.2015

Хотя я знаю, что это было для vb.net, я уверен, что вы можете использовать этот код С# с несколькими модификациями, это сработало для меня. Может быть, это не лучший способ сделать это, но для меня это был самый простой способ. Перед запуском второй копии он проверяет, запущено ли в данный момент название приложения.

Это в 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();
        }
    }
person jason    schedule 19.10.2012