Вызов метода другого потока или как сделать "Открыть через." - C#
Формулировка задачи:
Здравствуйте. Хочу сделать приложение со своим пунктом в контекстом меню Windows. Например "Открыть с помощью %название программы%". Попытался воспроизвести поведение текстовых редакторов, на примере sublimetext. Вставил ручками в реестр свой пункт меню, написал к нему такую же shell команду, которая по факту просто путь до exe файла + параметр "%1" передающий путь до файла. И создал простенькую форму, с 1 полем в котором отображается переданный параметр с путем до файла. Отображение идет через вызов простого метода с одним строчным параметром.
Нормальное поведение текстового редактора: при каждом вызове контекстного меню он в экземпляре своей первой запущенной программы создает еще один таб с редактируемым файлом.
Ненормальное поведение моей программы: при каждом вызове контекстного меню создается новый экземпляр программы и в каждом переданный параметр.
Пытался найти решение , накопал Windows Shell Extensions. Но он доступен с NET 4.0.
Отсюда вопрос, как это делалось до 4.0 ? Как при каждом вызове exe файла , передавать параметры уже существующему экземпляру программы ?
Все попытки найти инфу упирались в WCF. Можно как то проще вызвать метод на потоке другого процесса, учитывая что это тот же самый exe файл ? Или как то можно вызвать метод на полученном объекте Process (хотя по имени метода, он его не находит)?
Решение задачи: «Вызов метода другого потока или как сделать "Открыть через."»
textual
Листинг программы
class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
const uint WM_SETTEXT = 0x000C;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam);
static void Main(string[] args)
{
// Ищем главное окно процесса по его имени.
Process[] processes = Process.GetProcessesByName("WindowsFormsApplication1");
if (processes.Length == 0)
{
Console.WriteLine("Процесс не найден. Завершение работы.");
return;
}
IntPtr handle = processes[0].MainWindowHandle;
// Также окно можно искать по его классу и заголовку
// Класс окна и его дочерних элементов можно узнавать с помощью Spy++
// (VisualStudio -> Tools -> Spy++)
// Наверняка они будут различаться для различных версий .NET.
// IntPtr handle = FindWindow("WindowsForms10.Window.8.app.0.141b42a_r14_ad1", "Form1");
// Будем искать TextBox, обрабатывающий наши сообщения,
// по задаваемому нами вручную уникальному заголовку (тексту).
// В данном случае это сгенерированный GUID.
const string uniqueCaption = "{5DEF1E05-EC29-4505-B87A-F7F48DCB75A0}";
IntPtr hwndTextBox = FindWindowEx(handle, IntPtr.Zero,
"WindowsForms10.EDIT.app.0.141b42a_r14_ad1", uniqueCaption);
if (hwndTextBox != IntPtr.Zero)
{
SendMessage(hwndTextBox, WM_SETTEXT, IntPtr.Zero, "Some text");
}
}
}