如何设置焦点并在c#.net3.5中的按钮点击事件上启动已经运行的应用程序?

时间:2010-02-04 05:54:04

标签: c# .net focus exe launch

我一直在尝试使用互斥锁的代码,但我无法在按钮点击后打开我的exe 我成功地没有在按钮单击时在任务栏上创建应用程序的多个条目,但我的应用程序仅在我关闭我的表单时启动.. 我想按下按钮启动我的应用程序,如果应用程序已经启动,那么我需要专注于以前运行的应用程序.. 我怎么能够解决我的启动需求以及重新关注并重新打开该应用程序.. 我发送你的代码,我使用按钮点击事件和PLZ修改我的错误......

在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 个答案:

答案 0 :(得分:3)

这可以找到并切换到一个已经运行的进程,该进程与您尝试启动的进程相匹配。

[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 :(得分:1)

我回答了有关Delphi的问题。我解释说我没有Delphi的背景但我在C#中高度描述了我在C#中使用InterProcess Communication(IPC)和.NET远程处理的组件,不仅可以激活正在运行的实例,还可以转发命令行参数从第二个实例进入第一个实例。我链接到一个非常简单易用的组件,它包含了所有这些功能。它可能对你有用。

她的答案来自other question

  

实现这一目标的最佳方式实际上是   你的exe的启动代码。在   换句话说,让Explorer启动一个   那个exe的第二个副本   继续检测它已经存在   运行并让它发送消息   正在运行的实例。

     

就个人而言,我几乎没有   德尔福的经验,但我的方式   在.NET应用程序中这样做了   使用互斥锁和进程间   沟通渠道。

     

一般的想法是第一个   应用程序的实例会   开始,并开始收听IPC   渠道。它还会创建一个名为   进程间互斥。当第二个   实例启动,它将无法   创建同名的互斥锁   这意味着前一个例子   正在跑步,正在听电话   IPC频道。第二个例子   然后发送命令行参数   通过IPC和第一个实例   第一个实例对他们采取了行动。   然后第二个实例退出   显示任何UI。

     

我已为此上传了代码   组件(C#),链接如下。   我不相信它有任何外在的   依赖,我不知道是什么   等效的沟通机制   德尔福会 - 但希望如此   给你一些想法。

     

InstanceManager Component (C#)

答案 2 :(得分:0)

请注意,出于安全原因,不建议使用指定的互斥锁。任何进程(即使是在来宾帐户下运行的进程)都可以在进程启动之前创建具有相同名称的互斥锁。解决这些安全问题通常比仅使用命名互斥锁更困难。

要解决您的问题,您只需要存储流程处理程序或流程ID,然后查找具有该流程ID的窗口。这与任务管理器的工作方式类似。