Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Несколько входных аргументов


Автор: Xonxt 6.12.2010, 18:32
Доброе время суток.
Суть вот в чем. Есть некоторое приложение, которое должно встраиваться в контекстное меню проводника Windows. Т.е. пользователь кликает правой кнопкой по файлу, выбирает некий пункт меню, запускается приложение и делает что-то с этим файлом.

Сначала я добавил пункт в контекстное меню через реестр:
Код
HKEY_CLASSES_ROOT/*/shell/
Здесь я добавил нужный мне пункт меню: 
Код
HKEY_CLASSES_ROOT/*/shell/Do Something
HKEY_CLASSES_ROOT/*/shell/Do Something/command
 и в последнем прописал путь к приложению: 
Код
"C:\MyApp.exe" "%1"
 для того, чтобы оно могло получать файл как входной аргумент.

Далее пишется программа. Функция Main в Program.cs выглядит так: 
Код
[STAThread]
static void Main( string[] args )
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault( false );

    if ( args.Length != 0 )
        Application.Run( new Form1( args ) );
    else
        Application.Run( new Form1() );
}
А затем перехватываю аргумент в конструкторе Form1() и, собственно, если файл один, то все прекрасно работает. Но проблемы начинаются, когда файлов несколько. Вместо того, чтобы обработать несколько файлов в одном приложении, запускается по одной копии приложения на каждый файл.

Если делать это через командную строку. Ну т.е. 
Код
C:\MyApp.exe file1.dat file2.dat file3.dat
то всё прекрасно. А вот через контекстное меню...

Я погуглил и нашел, что надо для каждого запуска проверять, запущено ли уже приложение, и если да, то отправлять ему сообщение с этим аргументом и закрывать ненужную копию приложения.

Прежде чем я начал влезать в эти дебри с мьютексами и сообщениями, скажите, нет ли другого более простого способа? Заранее благодарен.

Автор: CYBERDREAM 6.12.2010, 19:43
Приветствую Xonxt, 
порой в сторону Single Instance Wrapper

Код

#region Region

using System.Collections.Generic;
using Microsoft.VisualBasic.ApplicationServices;
using Sample_Application;

#endregion

namespace sMs
{
    public class SingleInstanceWrapper : WindowsFormsApplicationBase
    {
        public SingleInstanceWrapper()
        {
            IsSingleInstance = true;
        }

        private App _app;

        protected override bool OnStartup(StartupEventArgs eventArgs)
        {
            _app = new App();
            _app.InitializeComponent();
            _app.Run();
            return false;
        }

        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
        {
            if (eventArgs.CommandLine.Count > 0)
                _app.Open(new List<string>(eventArgs.CommandLine));
        }
    }
}


Код

/// <summary>
    ///   Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        public void Open(List<String> massive)
        {
            MainWindow mw = MainWindow as MainWindow;
            if (mw != null)
                mw.Pro.Add(massive, null);
        }
    }


Добавлено через 6 минут и 11 секунд
Хотя конечно странно что несколько копий запускается. 

Автор: Xonxt 6.12.2010, 20:39
Может я здесь в реестре что-то неправильно пишу 
Код
"C:\MyApp.exe" "%1"

Всё-таки "%1" - это я заведомо указываю, что входной аргумент может быть только один. Может есть какой-нибудь другой более правильный способ. 

Или же проблема решается программированием. 

Автор: CYBERDREAM 6.12.2010, 21:34
а если прописываешь жестко 1 параметр, то как должна отработать программа, если отсылаешь несколько файлов через контекстное меню?

Автор: Xonxt 6.12.2010, 23:20
В общем, решил проблему. Как я и говорил: мьютексами и сообщениями. 
Мьютекс следит, чтобы было запущено не более одной копии приложения. Каждая последующая копия приложения отправляет свой входной аргумент в качестве сообщения первому приложению. 

Всем спасибо.

Автор: CYBERDREAM 7.12.2010, 08:45
а то что я предлагал разве не проще?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)