繁体   English   中英

使最小化/系统托盘应用程序 gui 从 C# 可见

[英]Make minimized/system tray application gui visible from c#

我有一个 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);

编辑:如果不清楚,我不是要让应用程序自己打开,而是要从我的应用程序中打开一个单独的供应商应用程序。

首先,您有点想重新发明轮子。 正如史蒂夫在评论中指出的那样,已经有用于实现单实例应用程序的内置方法,例如使用Mutex

然而,“当它最小化到托盘时显示它”部分是棘手的。

您可以遍历正在运行的进程以找到您的进程,然后可以选择启动一个新进程,或者调用已经运行的进程。 这需要一点 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)”?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM