C# 如何从进程还原隐藏的wpf窗口

C# 如何从进程还原隐藏的wpf窗口,c#,.net,wpf,ipc,C#,.net,Wpf,Ipc,在我的wpf窗口中,我隐藏窗口并在关闭时将其从任务栏中删除 如何从运行进程激活该窗口。我尝试了很多方法,但没有成功 下面是激活隐藏窗口的示例代码 private void checkIfProcessRunning() { // get the name of our process string proc = Process.GetCurrentProcess().ProcessName; // get the list of all proces

在我的wpf窗口中,我隐藏窗口并在关闭时将其从任务栏中删除

如何从运行进程激活该窗口。我尝试了很多方法,但没有成功

下面是激活隐藏窗口的示例代码

private void checkIfProcessRunning()
{           
    // get the name of our process
    string proc = Process.GetCurrentProcess().ProcessName;
    // get the list of all processes by that name
    Process[] processes = Process.GetProcessesByName(proc);
    // if there is more than one process...
    if (processes.Length > 1)
    {
    // Assume there is our process, which we will terminate, 
    // and the other process, which we want to bring to the 
    // foreground. This assumes there are only two processes 
    // in the processes array, and we need to find out which 
    // one is NOT us.
    RzLogger.WriteLine("process are running count:" + processes.Length);
        // get our process
        Process p = Process.GetCurrentProcess();
        int n = 0;        // assume the other process is at index 0
                          // if this process id is OUR process ID...
        if (processes[0].Id == p.Id)
        {
        RzLogger.WriteLine("other process are at 1");
        // then the other process is at index 1
        n = 1;
        }
        // get the window handle
        IntPtr hWnd = processes[n].MainWindowHandle;
    RzLogger.WriteLine("main handle is:" + hWnd);
        // if iconic, we need to restore the window
        if (IsIconic(hWnd))
        {
        RzLogger.WriteLine("is minimized");
        ShowWindowAsync(hWnd, SW_SHOWNORMAL);
        ShowWindowAsync(hWnd, SW_RESTORE);
        SetForegroundWindow(hWnd);

    }
    // bring it to the foreground
    SetForegroundWindow(hWnd);
    // exit our process
    Application.Current.Shutdown();
    return;
    }
    // ... continue with your application initialization here.

}
问题是我总是得到0的处理


有办法做到这一点吗?我不想在任务栏中显示任何内容,这里是一个如何使用管道的示例

如果您启动实例非常快(在这种情况下,您可能会有一台以上的服务器——因此,尽早创建一个命名互斥体,如果存在的话——只需通过管道发送Show()并关闭它),那么使用命名互斥体还可以解决一些问题

从VS2017默认Wpf项目创建。编译它,启动调试生成,转到输出文件夹并再次启动exe以显示它的功能

main window.xaml

<Window x:Class="interproc.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:interproc"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="350"
        Width="525"
        Loaded="Window_Loaded">
    <Grid>
        <TextBlock Name="tb"
                   Background="Yellow"
                   Text="..."
                   Margin="50" />
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Windows;
using System.IO.Pipes;
using System.Threading;
using System.Windows.Threading;

namespace InterprocessCommunicationViaPipes
{
    /// <summary>
    ///   Commands used to communiate via pipe 
    /// </summary>
    public enum EPipeCommands : byte
    {
        None, Show, Hide, Close
    };

    /// <summary>
    ///   Interaction logic for MainWindow.xaml 
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Title = DateTime.UtcNow.ToString("o");
        }

        /// <summary>
        ///   Name of the pipe used for interprocess communication 
        /// </summary>
        private const string PipeName = "MyCoolApp";

        /// <summary>
        ///   prevents double Close() calls 
        /// </summary>
        private bool isClosing = false;

        /// <summary>
        ///   Server 
        /// </summary>
        private NamedPipeServerStream pipeServerStream = null;

        /// <summary>
        ///   Thread server is running in 
        /// </summary>
        private Thread ServerThread;

        void ActOnPipeCommand(EPipeCommands c)
        {
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, 
                new ThreadStart(
                delegate
                {
                    tb.Text += $"\n{DateTime.UtcNow:o} recieved {c}\n";

                    switch (c)
                    {
                        case EPipeCommands.None:
                            return;

                        case EPipeCommands.Hide:
                            Hide();
                            break;

                        case EPipeCommands.Show:
                            if (this.WindowState == WindowState.Minimized)
                                WindowState = WindowState.Normal;

                            Visibility = Visibility.Visible;
                            break;

                        case EPipeCommands.Close when !isClosing:
                            Close();
                            break;

                        case EPipeCommands.Close:
                            tb.Text += $"Already closing.\n";
                            break;

                        default:
                            tb.Text += $"Unmapped pipe action: {c.ToString()}\n";
                            break;
                    }
                }));
        }

        /// <summary>
        ///   Server running? 
        /// </summary>
        /// <returns></returns>
        bool CheckIsRunning()
        {
            NamedPipeClientStream clientStream = new NamedPipeClientStream(PipeName);
            try
            {
                clientStream.Connect(1000);
            }
            catch (TimeoutException)
            {
                tb.Text = $"No Server found.";
                return false;
            }

            clientStream.WriteByte((byte)EPipeCommands.Show);
            return true;
        }

        EPipeCommands InterpretePipeCommand(int v)
        {
            if (Enum.TryParse<EPipeCommands>($"{v}", out var cmd))
                return cmd;

            return EPipeCommands.None;
        }

        /// <summary> Creates the server, listens to connectiontrys, 
        /// reads 1 byte & disconnects </summary> 
        /// <param name="data"></param>
        void PipeServer(object data)
        {
            pipeServerStream = new NamedPipeServerStream(
                PipeName, PipeDirection.InOut, 
                2, PipeTransmissionMode.Byte);

            do
            {
                pipeServerStream.WaitForConnection();

                if (pipeServerStream.IsConnected && !isClosing)
                {
                    ActOnPipeCommand(
                        InterpretePipeCommand(
                            pipeServerStream.ReadByte()));
                }
                pipeServerStream.Disconnect();
            }
            while (!isClosing);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (CheckIsRunning())
                Close();
            else
            {
                ServerThread = new Thread(PipeServer);
                ServerThread.Start();

                tb.Text = "Starting new pipe server.\n";

                Closing += (a, b) => isClosing = true;
            }
        }
    }
}
使用系统;
使用System.Windows;
使用System.IO.Pipes;
使用系统线程;
使用System.Windows.Threading;
命名空间进程间通信通道
{
/// 
///用于通过管道进行通信的命令
/// 
公共枚举EPipeCommands:字节
{
无、显示、隐藏、关闭
};
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
Title=DateTime.UtcNow.ToString(“o”);
}
/// 
///用于进程间通信的管道的名称
/// 
私有常量字符串PipeName=“mycolapp”;
/// 
///防止双重Close()调用
/// 
private bool isClosing=false;
/// 
///服务器
/// 
私有名称pipeServerStream pipeServerStream=null;
/// 
///线程服务器正在运行
/// 
私有线程服务器线程;
void ActOnPipeCommand(EPipeCommands c)
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,
新ThreadStart(
代表
{
tb.Text+=$“\n{DateTime.UtcNow:o}已收到{c}\n”;
开关(c)
{
案例EPIPECOMANDS。无:
回来
case EPipeCommands.Hide:
隐藏();
打破
案例EPIPECOMANDS。显示:
如果(this.WindowState==WindowState.Minimized)
WindowState=WindowState.Normal;
可见性=可见性。可见;
打破
案例EPIPECOMANDS。在!关闭时关闭:
Close();
打破
案例EPIPECOMANDS。结束:
tb.Text+=$“已关闭。\n”;
打破
违约:
tb.Text+=$“未映射的管道操作:{c.ToString()}\n”;
打破
}
}));
}
/// 
///服务器正在运行?
/// 
/// 
bool CheckIsRunning()
{
NamedPipeClientStream clientStream=新的NamedPipeClientStream(管道名称);
尝试
{
clientStream.Connect(1000);
}
捕获(超时异常)
{
tb.Text=$“未找到服务器。”;
返回false;
}
WriteByte((字节)EPipeCommands.Show);
返回true;
}
EPipeCommands命令(int v)
{
if(Enum.TryParse($“{v}”,out var cmd))
返回cmd;
返回EPipeCommands。无;
}
///创建服务器,侦听ConnectionSys,
///读取1字节并断开连接
/// 
无效PipeServer(对象数据)
{
pipeServerStream=新名称pipeServerStream(
PipeName,PipeDirection.InOut,
2,PipeTransmissionMode.Byte);
做
{
pipeServerStream.WaitForConnection();
if(pipeServerStream.IsConnected&!isClosing)
{
ActOnPipeCommand(
解释器命令(
pipeServerStream.ReadByte());
}
pipeServerStream.Disconnect();
}
而(!正在丢失);
}
已加载私有无效窗口(对象发送器、路由目标)
{
if(CheckIsRunning())
Close();
其他的
{
ServerThread=新线程(PipeServer);
ServerThread.Start();
tb.Text=“正在启动新管道服务器。\n”;
关闭+=(a,b)=>isClosing=true;
}
}
}
}

您是在谈论自己进程中的WPF窗口吗?还是正在尝试还原哪些窗口?您可以使用进程间消息连接到其他实例,并告诉它取消隐藏-。本质上,您创建了一个管道服务器,该服务器以某个名称进行侦听,如果您的应用程序重新启动,您可以使用一个全局命名的互斥来检查它是否可用s开始-如果是这样,你发射一个“取消隐藏”消息并终止您自己。通过使用全局互斥,您根本不需要查询进程列表。@mm8是WPF windowSo为什么不直接访问这些窗口?@mm8很抱歉造成混淆,但问题是我的窗口是隐藏的,并且在任务管理器中只有进程。当我再次运行相同的exe时,我想显示第一个exe并关闭此exe。