4 个解决方案
#1
改写自:如何操作我的程序的另一个实例
http://blog.csdn.net/gomoku/article/details/4798331
http://blog.csdn.net/gomoku/article/details/4798331
// Program.cs
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
// 尝试创建一个命名事件
bool createNew;
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, @"MyStartEvent", out createNew);
// 如果该命名事件已经存在(存在有前一个运行实例),则
if (!createNew)
{
// 先写一些数据到注册表中,以便传递给前一个运行实例
SetDataToRegistry(args.FirstOrDefault() ?? "空白");
// 发事件通知
ProgramStarted.Set();
// 将焦点转移到前一个实例
foreach (Process p in Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName))
{
if (p.MainWindowHandle != IntPtr.Zero)
{
SetForegroundWindow(p.MainWindowHandle);
}
}
// 就此退出第二个进程
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
internal static EventWaitHandle ProgramStarted;
internal static void SetDataToRegistry(string data)
{
Registry.SetValue(@"HKEY_CURRENT_USER\Software\MyMy", "", data);
}
internal static string GetDataFromRegistry()
{
return Registry.GetValue(@"HKEY_CURRENT_USER\Software\MyMy", "", "") as string;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
#2
// Form1.cs
using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
ListBox listBox = new ListBox() { Dock = DockStyle.Fill};
public Form1()
{
//InitializeComponent();
this.Controls.Add(listBox);
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
}
// 当收到第二个进程的通知时,从注册表中获得传入的参数,并恢复窗口显示
void OnProgramStarted(object state, bool timeout)
{
if (this.InvokeRequired)
{
this.Invoke(new WaitOrTimerCallback(OnProgramStarted), state, timeout);
}
else
{
listBox.Items.Add(Program.GetDataFromRegistry());
}
}
}
}
#3
string keyName;
string keyValue;
keyName = "MyApp";
keyValue = "My Application";
RegistryKey key;
key = Registry.ClassesRoot.CreateSubKey(keyName);
key.SetValue("", keyValue);
key = key.CreateSubKey("shell");
key = key.CreateSubKey("open");
key = key.CreateSubKey("command");
key.SetValue("", "C:\\myApp.exe %1");
keyName = ".bar"; //相应后缀
keyValue = "MyApp";
key = Registry.ClassesRoot.CreateSubKey(keyName);
key.SetValue("", keyValue);
程序入口
[STAThread]
static void Main(string[] args)
{
if(args.Length > 0)
Application.Run(new FrmMain(args[0])); //args[0] 就是双击打开的文件名(包含文件路径)
else
Application.Run(new FrmMain(null));
}
#4
进程间通讯方法太多了,简单参数用共享内存也行,像桌面应用这种,还可以向先打开的程序发送WM_COPYDATA消息
重写WndProc时捕获自处理一下就好(文件参数放在lPara中)
重写WndProc时捕获自处理一下就好(文件参数放在lPara中)
#1
改写自:如何操作我的程序的另一个实例
http://blog.csdn.net/gomoku/article/details/4798331
http://blog.csdn.net/gomoku/article/details/4798331
// Program.cs
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
// 尝试创建一个命名事件
bool createNew;
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, @"MyStartEvent", out createNew);
// 如果该命名事件已经存在(存在有前一个运行实例),则
if (!createNew)
{
// 先写一些数据到注册表中,以便传递给前一个运行实例
SetDataToRegistry(args.FirstOrDefault() ?? "空白");
// 发事件通知
ProgramStarted.Set();
// 将焦点转移到前一个实例
foreach (Process p in Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName))
{
if (p.MainWindowHandle != IntPtr.Zero)
{
SetForegroundWindow(p.MainWindowHandle);
}
}
// 就此退出第二个进程
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
internal static EventWaitHandle ProgramStarted;
internal static void SetDataToRegistry(string data)
{
Registry.SetValue(@"HKEY_CURRENT_USER\Software\MyMy", "", data);
}
internal static string GetDataFromRegistry()
{
return Registry.GetValue(@"HKEY_CURRENT_USER\Software\MyMy", "", "") as string;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
#2
// Form1.cs
using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
ListBox listBox = new ListBox() { Dock = DockStyle.Fill};
public Form1()
{
//InitializeComponent();
this.Controls.Add(listBox);
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
}
// 当收到第二个进程的通知时,从注册表中获得传入的参数,并恢复窗口显示
void OnProgramStarted(object state, bool timeout)
{
if (this.InvokeRequired)
{
this.Invoke(new WaitOrTimerCallback(OnProgramStarted), state, timeout);
}
else
{
listBox.Items.Add(Program.GetDataFromRegistry());
}
}
}
}
#3
string keyName;
string keyValue;
keyName = "MyApp";
keyValue = "My Application";
RegistryKey key;
key = Registry.ClassesRoot.CreateSubKey(keyName);
key.SetValue("", keyValue);
key = key.CreateSubKey("shell");
key = key.CreateSubKey("open");
key = key.CreateSubKey("command");
key.SetValue("", "C:\\myApp.exe %1");
keyName = ".bar"; //相应后缀
keyValue = "MyApp";
key = Registry.ClassesRoot.CreateSubKey(keyName);
key.SetValue("", keyValue);
程序入口
[STAThread]
static void Main(string[] args)
{
if(args.Length > 0)
Application.Run(new FrmMain(args[0])); //args[0] 就是双击打开的文件名(包含文件路径)
else
Application.Run(new FrmMain(null));
}
#4
进程间通讯方法太多了,简单参数用共享内存也行,像桌面应用这种,还可以向先打开的程序发送WM_COPYDATA消息
重写WndProc时捕获自处理一下就好(文件参数放在lPara中)
重写WndProc时捕获自处理一下就好(文件参数放在lPara中)