C# 如何从进程还原隐藏的wpf窗口
在我的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
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。