Откройте программу раз с несколькими файлами в качестве аргументов от Explorer
-
01-10-2019 - |
Вопрос
У меня есть программа, которая работает, когда файл открывается с помощью него, используя меню правой кнопкой мыши в Explorer. Но если я выберу несколько файлов, а затем щелкните правой кнопкой мыши и открываемся с моей программой, то она открывает несколько экземпляров моей программы, а не просто передачу нескольких файлов в качестве аргументов в один экземпляр. Программа написана в VB.NET, но не является формой Windows, это просто модуль, поэтому я могу отметить параметр «Один экземпляр» в свойствах Visual Studio.
Итак, как мне открывать несколько файлов из контекстного меню Explorer в одном экземпляре.
Решение
Нет счастливых ответов здесь, Windows Explorer не обеспечивает простого способа начать пропустить программу все Выбранные файлы. Это требует А. Обработчик контекстного меню оболочки, Они очень трудно написать в управляемом коде. И до .NET 4.0 не может быть безопасно написано.
Тем не менее, легко имитировать его с прикладнойской структурой, доступной в VB.NET, сделать ваше приложение Singleton и реализовать Стартовое событие. Отказ Единственным вопросом состоит в том, что это не особенно быстро. И что он не работает в приложениях в режиме консоли.
Другие советы
Эта ссылка помогла мне получать пути выбранных файлов в Explorer, нажав на элемент меню контекста:.NET Shell Extensions - контекстные меню
Это в языке C #, но, поскольку в том, что плакат статьи также можно использовать в VB.NET.
очень легко :)
Надеюсь, это поможет тебе тоже! :)
Вот шаги:
1) Скачать Thee Sharpshell Libbre >>
Загрузите ZIP-файл «Shakshell Libry» в верхней части статьи и добавьте ссылку на загруженный файл 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
Эта функция называется на самом деле создать контекстное меню. Стандартные винформы 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» для установки и регистрации расширения оболочки. При использовании REPASM расширение оболочки будет установлено в реестр (т. Е. Идентификатор класса COM-сервера будет помещен в раздел классов COM-сервера и связан с пути к фактическому файлу сервера), он также будет зарегистрировать ассоциации.
Инструмент менеджера сервера
Инструмент Manager Server является моим предпочтительным подходом для установки / удаления и регистрации / регистрации, по крайней мере, во время разработки, поскольку он позволяет устанавливать и регистрировать как отдельные шаги. Это также позволит вам указать, устанавливаете ли вы / удаление и т. Д. в 32-битный или 64-битный режим.
Это был весь образец Sourcecode. Мы можем добавить любое количество элементов контекстно-меню, любую функцию, любую файлостность и т. Д.
Пока я знаю, что это было для VB.NET, я уверен, что вы можете использовать этот код C # с несколькими модификациями, это работало для меня. Может быть, это не лучший способ сделать это, но для меня это был самый простой способ. Он проверяет, если заголовок приложения в данный момент работает перед запуском второй копии.
Это в программе .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();
}
}