Как установить фокус и запустить уже запущенное приложение на событие нажатия кнопки в c # .net3.5? - PullRequest
4 голосов
/ 04 февраля 2010

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

кодирование в program.cs

static void Main()  
{

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

    Application.Run(new Form1());
    System.Diagnostics.Process.Start("filename.exe");
}

:

кодирование выполнено вform1.cs

private void button1_Click(object sender, EventArgs e)
{
    try
    {
       bool createdNew;
       Mutex m = new Mutex(true, "e-Recording", out createdNew);
       System.Diagnostics.ProcessStartInfo f = new System.Diagnostics.ProcessStartInfo("C:\\windows\\system32\\rundll32.exe", "C:\\windows\\system32\\shimgvw.dll,ImageView_Fullscreen " + "filename.exe".TrimEnd(null));

        if (createdNew) Launch();

        else
        {
             MessageBox.Show("e-Recording is already running!", "Multiple Instances");
         }
     }
     catch (Exception ex)
     {
          System.Diagnostics.Debug.WriteLine(ex.ToString());
     }
}

Ответы [ 3 ]

3 голосов
/ 23 февраля 2010

Это позволит найти и переключиться на уже запущенный процесс, который соответствует тому, что вы пытаетесь запустить.

[DllImport( "user32.dll" )]
public static extern bool ShowWindowAsync( HandleRef hWnd, int nCmdShow );
public const int SW_RESTORE = 9;

public void SwitchToCurrent() {
  IntPtr hWnd = IntPtr.Zero;
  Process process = Process.GetCurrentProcess();
  Process[] processes = Process.GetProcessesByName( process.ProcessName );
  foreach ( Process _process in processes ) {
    // Get the first instance that is not this instance, has the
    // same process name and was started from the same file name
    // and location. Also check that the process has a valid
    // window handle in this session to filter out other user's
    // processes.
    if ( _process.Id != process.Id &&
      _process.MainModule.FileName == process.MainModule.FileName &&
      _process.MainWindowHandle != IntPtr.Zero ) {
      hWnd = _process.MainWindowHandle;

      ShowWindowAsync( NativeMethods.HRef( hWnd ), SW_RESTORE );
      break;
    }
  }
 }
1 голос
/ 04 февраля 2010

Я недавно отправил ответ на вопрос о Delphi.Я объяснил, что у меня нет фона в Delphi, но я на высоком уровне описал то, что сделал в C # для создания компонента, который использует InterProcess Communication (IPC) с удаленным взаимодействием .NET, чтобы не только активировать работающий экземпляр, но и переслатьпараметры командной строки из второго экземпляра в первый экземпляр.Я связался с довольно простым в использовании компонентом, который оборачивает всю эту функциональность.Это может быть полезно для вас.

Мой ответ Херса из другого вопроса :

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

Лично у меня практически нет опыта работы с Delphi,но в приложении .NET я использовал мьютекс и межпроцессный канал связи.

Общая идея состояла в том, что первый экземпляр приложения запустится и начнет прослушивать канал IPC.Это также создаст именованный межпроцессный мьютекс.При запуске второго экземпляра он не сможет создать мьютекс с тем же именем, что означает, что предыдущий экземпляр работал и прослушивал вызовы на канале IPC.Затем второй экземпляр отправил аргументы командной строки первому экземпляру через IPC, и первый экземпляр принял меры по ним.Затем второй экземпляр завершается без отображения пользовательского интерфейса.

Я загрузил код для этого компонента (C #), и ссылка приведена ниже.Я не верю, что у него есть какие-либо внешние зависимости, и я не знаю, каким будет эквивалентный механизм связи в Delphi - но, надеюсь, это даст вам некоторые идеи.

Компонент InstanceManager (C #)

0 голосов
/ 26 февраля 2010

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

Чтобы решить вашу проблему, вам просто нужно сохранить обработчик процесса или идентификатор процесса, а затем искать окно с этим идентификатором процесса.Это похоже на работу менеджера задач.

...