问题
I'm currently developing an mono application in c#, which I would like to start only once. I know, this can be achieved with mutex. But how can I bring the application to front using mono? I tried getting the Process via
Process.GetProcessByName("AudioCuesheetEditor")
but couldn't access the MainWindowHandle.
How can I bring the running application to front?
Thanks for you answers.
EDIT:
Now I have been able to get the MainWindowHandle, but it's a IntPtr. How do I bring this handle to front? I tried
Window wRunning = new Window(handle);
wRunning.Present();
but that gave me an exception :(.
回答1:
I have been able to fix it with a file system watcher:
FileSystemWatcher fswRunning = new FileSystemWatcher(Path.GetTempPath() + "AudioCuesheetEditor");
fswRunning.Filter = "*.txt";
fswRunning.Changed += delegate(object sender, FileSystemEventArgs e) {
log.debug("FileSystemWatcher called Changed");
if (pAudioCuesheetEditor != null)
{
log.debug("pAudioCuesheetEditor != null");
pAudioCuesheetEditor.getObjMainWindow().Present();
}
};
fswRunning.EnableRaisingEvents = true;
Boolean bAlreadyRunning = false;
Process[] arrPRunning = Process.GetProcesses();
foreach (Process pRunning in arrPRunning)
{
Boolean bCheckProcessMatch = false;
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
if (pRunning.HasExited == false)
{
log.debug("pRunning.ProcessName = " + pRunning.ProcessName + " pRunning.MainWindowTitle = " + pRunning.MainWindowTitle);
if (pRunning.ProcessName.ToLower().Contains("mono"))
{
for (int i = 0; i < pRunning.Modules.Count;i++)
{
if (pRunning.Modules[i].ModuleName.Contains("AudioCuesheetEditor"))
{
bCheckProcessMatch = true;
i = pRunning.Modules.Count;
}
}
}
}
}
else
{
log.debug("pRunning.ProcessName = " + pRunning.ProcessName);
if (pRunning.ProcessName == Process.GetCurrentProcess().ProcessName)
{
bCheckProcessMatch = true;
}
}
log.debug("bCheckProcessMatch == " + bCheckProcessMatch);
if ((pRunning.Id != Process.GetCurrentProcess().Id) && (bCheckProcessMatch == true))
{
log.info("Writing to file " + Path.GetTempPath() + "AudioCuesheetEditor" + Path.DirectorySeparatorChar + "message.txt");
File.WriteAllText(Path.GetTempPath() + "AudioCuesheetEditor" + Path.DirectorySeparatorChar + "message.txt","Present");
bAlreadyRunning = true;
}
}
log.debug("bAlreadyRunning = " + bAlreadyRunning);
if (bAlreadyRunning == false)
{
//Start Application
}
回答2:
Using a FSW for this seems like very hacky.
I think the most elegant solution is using IPC.
In particular, I would use DBus. In fact, it's what Banshee uses to avoid multiple instances of it being created. So go ahead and check out our source code if you're interested.
来源:https://stackoverflow.com/questions/17855227/start-application-only-once-mono