Ответ 1
ТЛ, д-р
Согласно документации MS, есть способ сделать это, установив pServerInfo в структуру BIND_OPTS2 для привязки прозвища. К сожалению, это не работает для прозвища класса COM.
см: https://msdn.microsoft.com/en-us/library/windows/desktop/ms694513(v=vs.85).aspx где он говорит для * pServerInfo:
COM new class moniker в настоящее время не соблюдает флаг pServerInfo.
Но, возможно, просто попробуйте свой сценарий, и в какой-то момент времени он может быть поддержан (или уже есть, и документация неверна).
также см.
http://thrysoee.dk/InsideCOM+/ch11c.htm
где также говорится в сноске, что это не работает для прозвища класса: http://thrysoee.dk/InsideCOM+/footnotes.htm#CH1104
Теория и предлагаемое решение, если она была поддержана в С#
Отказ от ответственности: я не мог проверить код, так как у меня нет тестовой настройки. Это от головы. Немного псевдокода.
Для этого вам придется вводить код COM/Moniker. Для этого вы можете взглянуть на источник реализации микрософт в качестве отправной точки. Там BindToMoniker реализован как:
public static Object BindToMoniker(String monikerName)
{
Object obj = null;
IBindCtx bindctx = null;
CreateBindCtx(0, out bindctx);
UInt32 cbEaten;
IMoniker pmoniker = null;
MkParseDisplayName(bindctx, monikerName, out cbEaten, out pmoniker);
BindMoniker(pmoniker, 0, ref IID_IUnknown, out obj);
return obj;
}
CreateBindCtx
, MkParseDisplayName
и BindMoniker
являются функциями OLE32.dll.
IBindCtx
имеет методы для изменения контекста привязки. Для этого вы вызываете IBindCtx.GetBindContext(out BIND_OPTS2)
и изменяете настройки на то, что вам нужно. Затем установите новый контекст привязки с IBindCtx.SetBindContext(BIND_OPTS2)
. Таким образом, ваша собственная версия кода будет выглядеть примерно так (псевдокод):
public static Object BindToMoniker(String monikerName)
{
Object obj = null;
IBindCtx bindctx = null;
CreateBindCtx(0, out bindctx);
BIND_OPTS2 bindOpts;
bindOpts.cbStruct = Marshal.SizeOf(BIND_OPTS2);
bindctx.GetBindOptions(ref bindOpts);
// Make your settings that you need. For example:
bindOpts.dwClassContext = CLSCTX_REMOTE_SERVER;
// Anything else ?
bindOpts.pServerInfo = new COSERVERINFO{pwszName = "serverName"};
bindctx.SetBindOptions(ref bindOpts);
UInt32 cbEaten;
IMoniker pmoniker = null;
MkParseDisplayName(bindctx, monikerName, out cbEaten, out pmoniker);
BindMoniker(pmoniker, 0, ref IID_IUnknown, out obj);
return obj;
}
Как уже говорилось, к сожалению, этот код нельзя писать в С# из коробки. Даже объявления метода OLE32.dll CreateBindCtx, MkParseDisplayName и BindMoniker конфиденциально объявляются в Marshal.cs, поэтому вам придется снова объявить их в своем проекте.
Но нам повезло с объявлением IBindCtx
, используя определение BIND_OPTS2
и определение структуры BIND_OPTS2. Они объявлены в Microsoft.VisualStudio.OLE.Interop
(интересные объявления в этом пространстве имен). Поэтому вы можете попробовать использовать их, потому что внутри объекта Marshal и marshal.cs используется только структура BIND_OPTS. Я не знаю, является ли это частью структуры и распространяемым (я сомневаюсь), но для тестирования это должно быть достаточно хорошим. Если это сработает, это может быть снова объявлено в вашем собственном решении.
Некоторая информация об используемых функциях:
BindMoniker
CreateBindCtx
MkParseDisplayName
BIND_OPTS2