Как использовать IPC, не будучи локальным администратором? - PullRequest
6 голосов
/ 18 июня 2010

В настоящее время я поддерживаю внутреннее приложение в .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

Обходной путь заключается в том, чтобы приложение требовало прав администратора.Это не работает по двум причинам:

  1. В противном случае это приложение не требует прав администратора
  2. Мы используем ClickOnce для развертывания наших внутренних инструментов, а ClickOnce не поддерживает ничего, кроме запускакак средство запуска процесса.

Итак, на данный момент мне нужно найти решение IPC, которое не требует привилегий администратора и позволяет мне достичь первоначальной цели: обнаружить уже запущенный экземпляр кода и сообщить егочто делать, иначе запускать сам.Будем весьма благодарны за любые предложения о том, что делать (в рамках .Net, сторонние решения не принимаются).

Ответы [ 2 ]

3 голосов
/ 18 июня 2010

Это невероятно сложно (и, как вы обнаружили, проблемный способ) обеспечить один сеанс работы вашего приложения.Вам следует просто изменить / повторить функцию, чтобы использовать мьютекс .

Вот еще один пример. И необходимая вики-статья о мьютексах .

РЕДАКТИРОВАТЬ

Чтобы обойти бит связи, вы можете сгенерировать временный файл со своим собственным специальным префиксом и / или расширением во временной папке, предоставляемой ОС, которую может использовать одно приложениеОпрос (фильтрация по вашему специальному префиксу и / или расширению), чтобы увидеть, было ли сделано больше запросов.См .:

System.IO.Path.GetTempFileName 

и

System.IO.Path.GetTempPath
2 голосов
/ 18 июня 2010

Определенно используйте с именем mutex , чтобы ограничить приложение одним экземпляром, затем вы можете использовать NamedPipeServerStream и NamedPipeClientStream для выполнения IPC, который не требуетправа администратора.

...