使最小化/系统托盘应用程序gui在c#中可见

本文关键字:gui 应用程序 最小化 系统 | 更新日期: 2023-09-27 18:14:50

我有一个windows表单应用程序,打开另一个供应商的应用程序。如果供应商的应用程序没有运行,我的代码打开它,它就会像预期的那样可见。但是,如果供应商的应用程序已经最小化运行或在系统托盘中,当我调用Process.Start()时,我无法使其可见。是否有一种方法,使当前运行的应用程序可见/显示,如果它是最小化或在系统托盘?

这是我打开其他应用程序的代码,只有在VendorProgram.exe未运行时才有效。如果VendorProgram.exe正在运行,但最小化它不会使它可见/显示,这是我所需要的。

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "C:''Program Files (x86)''VendorProgram.exe";
startInfo.WindowStyle = ProcessWindowStyle.Normal;

Process p = Process.Start(startInfo);

编辑:如果它不清楚,我不是试图使应用程序打开自己,我试图从我的应用程序打开一个单独的供应商的应用程序。

使最小化/系统托盘应用程序gui在c#中可见

首先,您在尝试重新发明轮子。正如Steve在评论中指出的那样,已经有了实现单实例应用程序的内置方法,比如使用互斥锁。

然而,"当它被最小化到托盘时显示它"这一部分是很棘手的。

你可以遍历正在运行的进程来找到你的进程,然后选择启动一个新的进程,或者调用已经在运行的进程。这需要一点p/invoke魔法:

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("user32.dll")]
private static extern Boolean SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);
var bFound = false;
foreach (var proc in Process.GetProcesses())
{
    if (proc.ProcessName.Equals("YourProcessName"))
    {
        var window = FindWindow(null, proc.MainWindowTitle);
        if (!window.Equals(IntPtr.Zero))
        {
            //Mixed results...this might be redundant
            SetForegroundWindow(window);
            ShowWindow(window, 1);  //SW_NORMAL
            bFound =true;
        }
    }
}
if (!bFound)
{
    var startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = false;
    startInfo.FileName = "C:''Program Files (x86)''Program.exe";
    startInfo.WindowStyle = ProcessWindowStyle.Normal;
    Process.Start(startInfo);
}

我发现了这个,它帮助我做了我需要的。

技巧是在FindWindow()而不是process.MainWindowTitle中使用正确的窗口名称。显然,process.MainWindowTitle会返回应用程序创建的第一个窗口。这可能有时有效,但并不总是有效。我需要把被最小化的实际窗口的名称放在系统托盘中。以记事本为例,如果标题是my file - Notepad,那么你就需要在FindWindow中添加这个。这看起来很笨拙,但对我来说每次都很有效。记事本不是我要打开的应用程序,但它是一个例子。

这行不通

foreach (var proc in Process.GetProcesses()) {
    if (proc.ProcessName.Equals("Notepad"))
    {
      IntPtr window = FindWindow(null, proc.MainWindowTitle);    
      ShowWindow(hWnd, 1);
      break;
    }
 }

这并

  IntPtr window = FindWindow(null, "my file - Notepad");   
  ShowWindow(hWnd, 1); 

你有没有试过使用

[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

代替"ShowWindow(IntPtr hWnd, int nCmdShow)"?