Подтвердить что ты не робот

Передача аргументов для запуска приложения

Я делаю загрузчик изображений (загружаю изображение на сайт хостинга изображений), и у меня возникают некоторые проблемы, передающие аргумент (расположение изображения для уже запущенного приложения)

  • Прежде всего, пусть MyApp.exe всегда работает
  • Всякий раз, когда я нажимаю на изображение, я добавил элемент в контекстном меню Windows по умолчанию, в котором говорится "Загрузить изображение".
  • При нажатии этой кнопки необходимо передать местоположение уже запущенному приложению.

Моя program.cs:

static class Program
{
    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, UIntPtr
    wParam, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint RegisterWindowMessage(string lpString);

    [STAThread]
    static void Main(params string[] Arguments)
    {
        if (Arguments.Length > 0)
        {
    //This means that the the upload item in the context menu is clicked
    //Here the method "uploadImage(string location)"
    //of the running application must be ran
        }
        else
        {
    //just start the application
            Application.Run(new ControlPanel());
        }
    }
}

Обратите внимание, что класс ControlPanel не имеет видимой формы, присутствует только значок в трее, поскольку форма не нужна.

Могу ли я получить помощь в том, как это сделать?

4b9b3361

Ответ 1

Я понял это, поэтому огромное спасибо за человека, который разместил ссылку http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a5bcfc8a-bf69-4bbc-923d-f30f9ecf5f64, это именно то, что я искал

Здесь a полное решение:

static class Program
{
    [STAThread]
    static void Main(params string[] Arguments)
    {
        SingleInstanceApplication.Run(new ControlPanel(), NewInstanceHandler);
    }

    public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)
    {
        string imageLocation = e.CommandLine[1];
        MessageBox.Show(imageLocation);
        e.BringToForeground = false;
        ControlPanel.uploadImage(imageLocation);
    }

    public class SingleInstanceApplication : WindowsFormsApplicationBase
    {
        private SingleInstanceApplication()
        {
            base.IsSingleInstance = true;
        }

        public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
        {
            SingleInstanceApplication app = new SingleInstanceApplication();
            app.MainForm = f;
            app.StartupNextInstance += startupHandler;
            app.Run(Environment.GetCommandLineArgs());
        }
    }  
}

Спасибо всем, и особенно человеку, который опубликовал эту ссылку, о которой я упоминал выше, но, я думаю, он удалил свой ответ?

С уважением, Кенни

Ответ 2

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

  • Каталог, просматриваемый вашим приложением и файлом, добавляется после его добавления в каталог.
  • Порт, в который другие приложения могут отправлять информацию.
  • Самостоятельный веб-сервис, который принимает изображения.
  • Порт TCP, который принимает изображения.
  • Именованный канал.
  • ....

Как видите, есть несколько возможностей. Правильный для вас зависит от вашего сценария. Файловая система - это опция, которая может быть легко реализована с помощью FileSystemWatcher для образца здесь.

Самостоятельное веб-приложение предоставляет веб-службу, которая может получать изображения. См. здесь для образца.

IMHO, это два наиболее простых варианта. Но... есть еще несколько.

Для порта TCP см. пост Tim.

Ответ 3

Предполагая, что у вас есть контроль над средой исполнения, приложение-слушатель может просто выставить конечную точку с использованием WCF или даже сырого TCP-сокета. Таким образом, любое другое приложение может подключаться к нему динамическим, но структурированным способом.

Несмотря на то, что отправитель и получатель находятся на одной машине, использование сетевого транспорта (например, WCF или TCP) - отличный способ безопасно отправлять данные через процессы.

Вот пример того, как это сделать в TCP с помощью С#: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server

WCF может быть немного сложнее (отчасти благодаря гибкости, а также из-за ограничений сериализации), но есть много документации в Интернете о том, как ее использовать. WCF - это более объектно-ориентированное решение, поскольку могут генерироваться классы прокси, которые позволяют вам делать строго типизированные вызовы для реальных объектов, а не просто отправлять сообщения.

Ответ 4

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

Итак, прежде всего создайте статическую ссылку на исходный экземпляр формы (MainForm).

Затем при последующей отправке аргументов NewInstanceHandler может использовать сохраненную ссылку на форму для доступа к ее общедоступным методам/свойствам (в моем случае, установщик под названием AddItem).

Простым способом проверить это является добавление публичного свойства в форму с помощью установщика для изменения текстового свойства формы (текст заголовка).

[STAThread]
    static Form1 MainForm;

    static void Main(params string[] Arguments)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        MainForm = new Form1();
        SingleInstanceApplication.Run(MainForm, NewInstanceHandler);
    }

    public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)
    {
        MainForm.AddItem = e.CommandLine[1];
        e.BringToForeground = false;
    }

    public class SingleInstanceApplication : WindowsFormsApplicationBase
    {
        private SingleInstanceApplication()
        {
            base.IsSingleInstance = true;
        }

        public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
        {
            SingleInstanceApplication app = new SingleInstanceApplication();
            app.MainForm = f;
            app.StartupNextInstance += startupHandler;
            app.Run(Environment.GetCommandLineArgs());
        }
    } 

Ответ 5

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

static class Program
{
    [STAThread]

   static void Main(params string[] Arguments)
   {
        Form1 MainForm;
        bool bInstanceFlag;

        Mutex MyApplicationMutex = new Mutex(true, "MyApp_Mutex", out bInstanceFlag);

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

        if (!bInstanceFlag)
        {
           MainForm = new Form1();
        SingleInstanceApplication.Run(MainForm, NewInstanceHandler);
    }
    else
    {
        MainForm = new Form1();
        SingleInstanceApplication.Run(MainForm, NewInstanceHandler);
        MainForm.Close();
    }
}

public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)
{
    MainForm.AddItem = e.CommandLine[1];
    e.BringToForeground = false;
}

public class SingleInstanceApplication : WindowsFormsApplicationBase
{
    private SingleInstanceApplication()
    {
        base.IsSingleInstance = true;
    }

    public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
    {
        SingleInstanceApplication app = new SingleInstanceApplication();
        app.MainForm = f;
        app.StartupNextInstance += startupHandler;
        app.Run(Environment.GetCommandLineArgs());
    }
}
}