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

发布于 2024-08-20 04:51:49 字数 1161 浏览 10 评论 0原文

我一直在尝试使用互斥体的代码,但单击按钮后无法打开我的 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());
     }
}

i have been trying the code using mutex but im unable to open my exe after button click
im successful in not making the multiple entries of the application on the taskbar at button click but my application is launched only when i close my form..
i want to launch my application on button click and if the application is already launched then i need to focus on the previous running application..
how could i able to resolve my need to launch as well as focusin and reopening that application again..
im sending u my code that im using on button click event and plz modify my errors...

coding at program.cs

static void Main()  
{

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

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

:

coding done at 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());
     }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

随遇而安 2024-08-27 04:51:49

这能够找到并切换到与您尝试启动的进程相匹配的已运行进程。

[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;
    }
  }
 }

This is be able to find and switch to an already running process that matches what you are trying to start.

[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;
    }
  }
 }
梦幻的心爱 2024-08-27 04:51:49

我不久前发布了有关 Delphi 问题的答案。我解释说,我没有 Delphi 背景,但我在较高层次上描述了我在 C# 中所做的工作,以构建一个使用进程间通信 (IPC) 和 .NET 远程处理的组件,不仅可以激活正在运行的实例,还可以转发将命令行参数从第二个实例传入第一个实例。我链接到一个非常简单易用的组件,它包含了所有这些功能。它可能对你有用。

她是我的答案 其他问题

做到这一点的最佳方法实际上是
你的exe的启动代码。在
换句话说,让 Explorer 启动一个
exe 的第二个副本,然后
继续检测它已经
运行并让它发送消息到
正在运行的实例。

就我个人而言,我几乎没有
使用 Delphi 的经验,但我的方式
在 .NET 应用程序中执行此操作是
使用互斥体和进程间
沟通渠道。

总体思路是第一个
应用程序的实例将
启动并开始监听 IPC
渠道。它还会创建一个命名的
进程间互斥。当第二个
实例启动后,将无法
创建同名的互斥体
这意味着前一个实例
正在运行并监听呼叫
IPC 通道。第二个实例
然后发送命令行参数
到第一个通过 IPC 的实例
第一审法院对他们采取了行动。
然后第二个实例退出,没有
显示任何用户界面。

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

InstanceManager 组件 (C#)

I posted an answer a while back to a question about Delphi. I explained that I didn't have a background in Delphi but I described at a high level what I did in C# to build a component that uses InterProcess Communication (IPC) with .NET remoting to not only activate a running instance, but also forward the command line parameters from the second instance into the first instance. I linked to a pretty simple to use component that wraps all this functionality up. It may be useful to you.

Hers's my answer from the other question:

The best way to do this is actually in
the the startup code of your exe. In
other words, let Explorer launch a
second copy of the exe which then
proceeds to detect that it is already
running and have it send a message to
the running instance.

Personally, I have practically no
experience with Delphi, but the way I
did this in a .NET application was
using a mutex and an interprocess
communication channel.

The general idea was that the first
instance of the application would
start, and begin listening on an IPC
channel. It would also create a named
interprocess mutex. When the second
instance launched, it would be unable
to create the mutex of the same name
which meant that a previous instance
was running and listening for calls on
the IPC channel. The second instance
then sent the command line arguments
to the first instance over IPC and the
first instance took action on them.
The second instance then exits without
showing any UI.

I've uploaded the code for this
component (C#) and the link is below.
I don't believe it has any external
dependencies and I don't know what the
equivalent communication mechanism in
Delphi would be - but hopefully this
gives you some ideas.

InstanceManager Component (C#)

梦与时光遇 2024-08-27 04:51:49

请注意,出于安全原因,不鼓励使用命名互斥体。任何进程(甚至在来宾帐户下运行的进程)都可以在进程启动之前创建同名的互斥体。解决这些安全问题通常比根本不使用命名互斥体更困难。

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

Note that usage of named mutexes is discouraged for security reasons. Any process (even one running under guest account) can create a mutex with the same name before your process was started. Solving these security problems is usually harder than just not using named mutex at all.

To solve your problem, you just need to store process handler or process ID and then look for a window with that process ID. This is similar to the way task manager works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文