Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使最小化/系统托盘应用程序gui从c可见#_C#_.net_Winforms_Process - Fatal编程技术网

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

C# 使最小化/系统托盘应用程序gui从c可见#,c#,.net,winforms,process,C#,.net,Winforms,Process,我有一个windows窗体应用程序,可以打开其他供应商的应用程序。如果供应商的应用程序未运行,“我的代码”将打开它,它将按预期显示。但是,如果供应商的应用程序已经在运行或在系统托盘中,则在调用Process.Start()时,无法使其可见。是否有办法使当前运行的应用程序可见/显示,无论是最小化还是在系统托盘中 这是我打开另一个应用程序的代码,该应用程序只有在VendorProgram.exe未运行时才能工作。如果VendorProgram.exe正在运行,但最小化了,则不会使其可见/显示,这就是

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

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

首先,你有点想重新发明轮子。正如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)”不同?

请仔细阅读,当外部应用程序在任务栏(而不是任务栏)中时,没有标准的方法让它“显示自己”.@Idle\u Mind的“无标准方法”是指它不可能从
.net/c
中实现吗?不……在Windows中,没有简单或万无一失的方法从托盘“恢复”应用程序。使用托盘图标时显示的窗口/表单可能与最初启动应用程序时显示的表单相同,也可能不同;应用程序可能会创建表单的新实例。换句话说,主窗体和托盘图标不一定相互绑定。据我所知,也没有windows消息可以发送到任务栏图标以使其“还原”…我只是试图从c#打开正在运行的应用程序的gui,而不是重新发明轮子。您的示例看起来很有希望,但无论是最小化还是在系统托盘中,它都没有打开正在运行的进程的形式
SetForeground
ShowWindow
没有执行任何操作。您可以尝试不使用
window
变量,而是将其用法替换为
proc.MainWindowHandle
FindWindow
将找到第一个匹配项,可能它返回了错误的句柄。
MainWindowHandle
也没有这样做。