从c#中可以看到最小化/系统托盘应用程序gui

时间:2015-09-28 19:27:00

标签: c# .net winforms process

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

编辑:如果不清楚,我不打算让应用程序自行打开,我试图从我的应用程序中打开一个单独的供应商的应用程序。

3 个答案:

答案 0 :(得分:2)

首先,你有点想重新发明轮子。正如史蒂夫在评论中指出的那样,已经有内置的方法来实现单实例应用程序,例如使用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);
}

答案 1 :(得分:1)

我找到了this,它帮助我做了我需要的事情。

诀窍是在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); 

答案 2 :(得分:1)

你尝试使用

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

而不是" ShowWindow(IntPtr hWnd,int nCmdShow)"?