В настоящее время я поддерживаю внутреннее приложение в .Net.Приложение использует IPC для поддержки одного запущенного сеанса за раз;если другая попытка открыть сеанс (кто-то снова щелкает по значку, кто-то открывает сохраненный файл результатов), второй сеанс сообщает об этом первому сеансу, а затем завершается, причем первый сеанс затем запускает запрошенное действие.
В настоящее время я делаю это, используя пространство имен System.ServiceModel, например:
пространство имен EventLogViewer.IPCServer {// Предоставляет общую платформу для процессов, чтобы общаться друг с другом.
[ServiceContract(Namespace = "http://ELV.domain")]
interface IELVLauncher
{
[OperationContract]
bool LaunchTabs(String[] fileNames);
}
public delegate void TabLauncher(String[] fileNames);
class ELVLauncherServer : IDisposable
{
ServiceHost ipcService;
public ELVLauncherServer()
{
Uri baseAddress = new Uri("Http://localhost:45600/elvlauncher/service");
String address = "net.pipe://localhost/elvlauncher/tablauncher";
ipcService = new ServiceHost(typeof(ELVLauncher), baseAddress);
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
ipcService.AddServiceEndpoint(typeof(IELVLauncher), binding, address);
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://localhost:45601/elvlauncher");
ipcService.Description.Behaviors.Add(behavior);
Utilities.WriteMemoryDebugStatement(new DebugStatement(DebugStatement.StatementType.INFO, "Registering IPC Service"));
ipcService.Open();
}
#region IDisposable Members
public void Dispose()
{
ipcService.Close();
}
#endregion
}
public class ELVLauncher : IELVLauncher
{
#region IELVLauncher Members
public bool LaunchTabs(string[] fileNames)
{
try
{
Utilities.WriteMemoryDebugStatement(new DebugStatement(DebugStatement.StatementType.INFO, String.Format("IPC request received, files: {0}", String.Join(", ", fileNames))));
Program.mainWindow.backgroundListener_OnLaunchRequestReceived(fileNames);
}
catch (Exception exception)
{
Utilities.WriteMemoryDebugStatement(new DebugStatement(exception));
}
return (true);
}
#endregion
}
ЭтоКод был изначально разработан под Windows XP, как и большинство корпораций, мы не перешли на Vista.Поскольку все мы работаем как локальные администраторы, этот код выполнялся без проблем.
Однако сейчас мы переходим на Win 7, и этот код создает исключение при запуске, поскольку он не может зарегистрировать конечную точку IPC.Более подробная информация находится здесь: http://mark.michaelis.net/Blog/WindowsCommunicationFoundationWithWindowsVistaAndUAC.aspx
Обходной путь заключается в том, чтобы приложение требовало прав администратора.Это не работает по двум причинам:
- В противном случае это приложение не требует прав администратора
- Мы используем ClickOnce для развертывания наших внутренних инструментов, а ClickOnce не поддерживает ничего, кроме запускакак средство запуска процесса.
Итак, на данный момент мне нужно найти решение IPC, которое не требует привилегий администратора и позволяет мне достичь первоначальной цели: обнаружить уже запущенный экземпляр кода и сообщить егочто делать, иначе запускать сам.Будем весьма благодарны за любые предложения о том, что делать (в рамках .Net, сторонние решения не принимаются).