Ответ 1
Один из возможных ответов на ваш вопрос "Как другое приложение, просто запустив, сломает наше собственное приложение...":
- В другом приложении также используется WCF NetNamedPipeBinding.
- Оба приложения создают конечные точки службы, используя базовые + относительные URL-адреса.
- Выбор базового адреса приложений и HostNameComparisonMode таков, что существует столкновение имен между приложениями на одном из вариантов URL, используемых клиентом -side WCF, чтобы найти метаданные для службы.
Я понятия не имею, действительно ли служба Garmin использует WCF NetNamedPipeBinding, но это одна из возможностей, которую вы должны исследовать. Эту проблему можно избежать всегда используя абсолютные URL-адреса для конечных точек NetNamedPipe.
ОК, поэтому, следуя обновлениям вопроса, мы теперь знаем, что служба Garmin использует WCF NetNamedPipeBinding, и мы знаем, что ваше приложение регистрирует свою службу с использованием абсолютного адреса, поэтому приведенное выше объяснение не является полной историей.
Вот еще одна гипотеза:
- Предположим, что служба Garmin работает в процессе, который имеет привилегию безопасности SeCreateGlobalPrivilege (которую служба Windows будет иметь, если специально не закодирована, чтобы отключить эту привилегию).
- Предположим, что он также регистрирует свою конечную точку Named Pipe WCF с базовым адресом net.pipe://localhost и относительными адресами конечных точек.
- Теперь его метаданные службы будут опубликованы с использованием объекта сопоставления общей памяти с именем в глобальном пространстве имен.
- Ваше служебное приложение не является службой Windows. Моя гипотеза заключается в том, что у ее процесса нет привилегии безопасности SeCreateGlobalPrivilege. Если это так, его метаданные службы будут опубликованы с использованием объекта сопоставления общей памяти только в пространстве имен локального сеанса.
- Теперь ваш клиентский процесс пытается инициировать соединение, когда служба Garmin запущена... стек канала на стороне клиента WCF. Элемент NetNamedPipeBinding пытается найти метаданные службы для вашей службы на основе вашего URL-адреса службы net.pipe://локальный/MyWCFConnection. Как поясняется в приведенной выше ссылке, он будет выполнять поиск, используя различные варианты URL-адреса службы, в свою очередь, чтобы получить имя для объекта общей памяти, содержащего метаданные. Сначала он просматривается в глобальном пространстве имен, для полного списка вариантов по очереди, прежде чем смотреть в пространство имен.
- В этом случае первая попытка будет для имени, полученного из "net.pipe://+/MyWCFConnection", и, по-видимому, ему не удается найти объект с этим именем в глобальном пространстве имен.
- Однако вторая попытка будет основана на варианте "net.pipe://+/", и это будет соответствовать имени сопоставления общей памяти службы Garmin, опубликованного в глобальном пространстве имен. Из-за порядка поиска он никогда не попадет в ваши метаданные службы, опубликованные в пространстве имен локального сеанса.
- Ваш клиент пытается подключиться к сервисному каналу Garmin. Предположим, что у службы Garmin есть определенная безопасность, которая приводит к отказу вашего клиента от отказа в доступе (например, он может установить ACL на своем канале). Результат может выглядеть как EndpointNotFoundException. [ LATER EDIT: На самом деле, скорее всего, происходит то, что ваш клиент фактически подключается к сервису Garmin, инициируя рукопожатие с преамбулой протокола кадрирования и получая отказ от отказа протокола кадров (http://schemas.microsoft.com/ws/2006/05/framing/faults/EndpointNotFound), потому что URL-адрес, запрошенный в записи Via, не будет соответствовать ожидаемому сервису Garmin. После этого связывание прекращает соединение и всплывает эта ошибка для вашего клиентского кода как исключение EndpointNotFoundException.]
Что вы можете сделать? Я бы предложил:
- Если вышеупомянутая гипотеза или что-то подобное может быть подтверждено, и Garmin использует базовую + относительную адресацию с базой только net.pipe://localhost, лучше всего было бы заставить их владеть проблемой: они могли бы исправить такие проблема очень легко, изменив их базовый адрес на нечто более вероятное, чтобы быть уникальным.
- Возможно, вы можете обойти это, найдя какой-то способ для вашего приложения-службы работать с привилегией безопасности SeCreateGlobalPrivilege: это непросто, не делая его службой Windows или работая как администратор, но, возможно, не исключая. Затем ваши метаданные также будут опубликованы в глобальном пространстве имен, и поиск клиента найдет его перед Garmin's.
- [Редактировать позже] Возможно, существует обходное решение, связанное с установкой свойства HostNameComparisonMode привязки к Exact и использованием синонима для localhost как главной части URL-адреса службы (например, net.pipe://127.0.0.1/MyWCFConnection). Это может вести поиск по вариантам Garmin, чтобы ваш клиент имел возможность рассматривать имена в пространстве имен Local session. Я не знаю, что это сработает, но стоит попробовать, я бы подумал.
- И очень длинный снимок: Есть ли у вашей компании отношения с Microsoft? Возможно, это серьезный недостаток дизайна в WCF: если вы беспокоитесь об этом, возможно, вы захотите, чтобы Microsoft выпустила патч QFE для него, например. чтобы предоставить свойство привязки, чтобы сообщить стеке на стороне клиента только попробовать пространство имен Local.