J'ai fait une application qui fonctionne de cette façon. Il utilise des messages Windows pour communiquer. Donc, dans la seconde, vous n'avez besoin que du handle du MainForm en premier lieu. J'ai enregistré ce handle dans un paramètre ClickOnce nommé hwnd.
using ProjectApplicationTemplate.Properties;
using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.Hosting;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace ProjectApplicationTemplate
{
static class Program
{
static Mutex mutex = new Mutex(true, guid());
static string guid()
{
// http://stackoverflow.com/questions/502303/how-do-i-programmatically-get-the-guid-of-an-application-in-net2-0
Assembly assembly = Assembly.GetExecutingAssembly();
var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
return attribute.Value;
}
static int MainWindowHandle
{
get
{
Settings.Default.Reload();
return Settings.Default.hwnd;
}
set
{
Settings sett = Settings.Default;
sett.hwnd = value;
sett.Save();
}
}
public static string GetFileName()
{
ActivationArguments a = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
// aangeklikt bestand achterhalen
string[] args = a == null ? null : a.ActivationData;
return args == null ? "" : args[0];
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
#region standaard
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
#endregion
MainForm frm = new MainForm();
MainWindowHandle = (int)frm.Handle;
Application.Run(frm);
MainWindowHandle = 0;
mutex.ReleaseMutex();
}
else
{
int hwnd = 0;
while (hwnd == 0)
{
Thread.Sleep(5);
hwnd = MainWindowHandle;
}
Win32.CopyDataStruct cds = new Win32.CopyDataStruct();
try
{
string data = GetFileName();
cds.cbData = (data.Length + 1) * 2; // number of bytes
cds.lpData = Win32.LocalAlloc(0x40, cds.cbData); // known local-pointer in RAM
Marshal.Copy(data.ToCharArray(), 0, cds.lpData, data.Length); // Copy data to preserved local-pointer
cds.dwData = (IntPtr)1;
Win32.SendMessage((IntPtr)hwnd, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
}
finally
{
cds.Dispose();
}
}
}
}
}
Et dans votre MainForm
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Windows.Forms;
namespace ProjectApplicationTemplate
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
OpenFile(Program.GetFileName());
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case Win32.WM_COPYDATA:
Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
string strData = Marshal.PtrToStringUni(st.lpData);
OpenFile(strData);
Activate();
break;
default:
// let the base class deal with it
base.WndProc(ref m);
break;
}
}
void OpenFile(string filename)
{
if (filename == "") return;
if (!File.Exists(filename)) return;
IDocument[] vensters = MdiChildren.Select(T => (IDocument)T).Where(T => T.CurrentFileName == filename).ToArray();
if (vensters.Length == 0)
{
ChildForm frm = new ChildForm();
frm.OpenFile(filename);
frm.MdiParent = this;
frm.Show();
}
else
{
vensters[0].Activate();
}
}
private void fileMenu_DropDownOpening(object sender, EventArgs e)
{
IDocument active = (IDocument)ActiveMdiChild;
if (active == null)
{
saveToolStripMenuItem.Enabled = false;
saveAsToolStripMenuItem.Enabled = false;
printToolStripMenuItem.Enabled = false;
printSetupToolStripMenuItem.Enabled = false;
printPreviewToolStripMenuItem.Enabled = false;
}
else
{
saveToolStripMenuItem.Enabled = active.Changed;
saveAsToolStripMenuItem.Enabled = true;
printToolStripMenuItem.Enabled = active.CanPrint;
printSetupToolStripMenuItem.Enabled = active.CanPrint;
printPreviewToolStripMenuItem.Enabled = active.CanPrint;
}
// fill the MRU-list
tmiOnlangsGeopend.DropDownItems.Clear();
string RecentFolder = Environment.GetFolderPath(Environment.SpecialFolder.Recent);
string[] bestanden = Directory.GetFiles(RecentFolder).Where(T => T.EndsWith(".text.lnk")).ToArray();
if (bestanden.Length == 0)
{
tmiOnlangsGeopend.DropDownItems.Add(new ToolStripMenuItem(Properties.Resources.NoRecent) { Enabled = false });
}
else
{
foreach (string bestand in bestanden.OrderBy(T => File.GetLastWriteTime(T)).Reverse())
{
ToolStripMenuItem tmi = new ToolStripMenuItem(Path.GetFileNameWithoutExtension(bestand.Substring(0, bestand.Length - 4)));
tmi.Click += delegate { OpenFile(ResolveShortCut(bestand)); };
tmiOnlangsGeopend.DropDownItems.Add(tmi);
}
}
}
string ResolveShortCut(string shc)
{
// Add Reference -> COM -> Windows Script Host Object Model
if (File.Exists(shc))
{
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
IWshRuntimeLibrary.IWshShortcut link = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(shc);
return link.TargetPath;
}
else
{
return "";
}
}
}
}
Win32.cs
using System;
using System.Runtime.InteropServices;
namespace ProjectApplicationTemplate
{
public partial class Win32
{
public const int WM_COPYDATA = 0x004A;
public struct CopyDataStruct : IDisposable
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
public void Dispose()
{
if (this.lpData != IntPtr.Zero)
{
LocalFree(this.lpData);
this.lpData = IntPtr.Zero;
}
}
}
/// <summary>
/// The SendMessage API
/// </summary>
/// <param name="hWnd">handle to the required window</param>
/// <param name="Msg">the system/Custom message to send</param>
/// <param name="wParam">first message parameter</param>
/// <param name="lParam">second message parameter</param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref CopyDataStruct lParam);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LocalAlloc(int flag, int size);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LocalFree(IntPtr p);
}
}
Si quelqu'un veut un peu plus d'informations à ce sujet: http://pieterjan.pro/?a=Projecten_csharp_DrawIt.php
Et celui-ci est modèle aC# avec plein de choses: - péché l'application gle instance avec fichier-associations - Localisation (lors de l'exécution ainsi) - MDI et de l'interface pour parcourir l'utilisateur des commandes - Vérification des mises à jour - liste utilisée plus récemment
http://pieterjan.pro/Projecten/csharp/ProjectApplicationTemplate.zip
Peut-être que si vous accepté certaines réponses, vous seriez plus enclin à obtenir une bonne aide – Brendan
duplication possible de [Comment puis-je créer une application d'instance unique en utilisant Click Once?] (http://stackoverflow.com/questions/248721/how-can-i -build-a-single-instance-application-using-click-once) –