Передача аргументов для запуска приложения
Я делаю загрузчик изображений (загружаю изображение на сайт хостинга изображений), и у меня возникают некоторые проблемы, передающие аргумент (расположение изображения для уже запущенного приложения)
- Прежде всего, пусть 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 не имеет видимой формы, присутствует только значок в трее, поскольку форма не нужна.
Могу ли я получить помощь в том, как это сделать?
Ответы
Ответ 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());
}
}
}