С помощью стандартного открытого метода вы не сможете контролировать, какой экземпляр запуска будет использоваться. Под капотом он использует DDE, и это undetermined, экземпляр которого будет обрабатывать DDE-запросы.
То же самое происходит, если вы используете Activator.GetObject
.
К счастью, в ole32.dll мы можем позвонить GetRunningObjectTable и оттуда перечислить все экземпляры, чтобы найти все зарегистрированные OLE-серверы для каждого экземпляра и который включает в себя все процессы Visual Studio.
Как только мы его найдем, вы можете получить экземпляр для интерфейса OLE Automation, EnvDTE и использовать его для инспектирования, если это подходящий экземпляр для взаимодействия, и если да, выполните любую команду, которая нам интересна , например, для загрузки файла.
private void OpenFileExecute(string file)
{
IRunningObjectTable ir;
// get all OLE/COM Automation servers
GetRunningObjectTable(0, out ir);
if (ir != null)
{
IEnumMoniker moniker;
// Get an enumerator to iterate over them
ir.EnumRunning(out moniker);
if (moniker != null)
{
moniker.Reset();
IMoniker[] results = new IMoniker[1];
// iterate
while (moniker.Next(1, results, IntPtr.Zero) == 0)
{
// we need a Bind Context
IBindCtx bindCtx;
CreateBindCtx(0, out bindCtx);
// what is the name of the OLE/COM Server
string objName;
results[0].GetDisplayName(bindCtx, null, out objName);
// what have we got ...
Trace.WriteLine(objName);
// I test with VS2010 instances,
// but feel free to get rid of the .10
if (objName.StartsWith("!VisualStudio.DTE.10"))
{
object dteObj; //
ir.GetObject(results[0], out dteObj);
// now we have an OLE automation interface
// to the correct instance
DTE dteTry = (DTE)dteObj;
// determine if this is indeed
// the one you need
// my naive approach is to check if
// there is a Document loaded
if (dteTry.Documents.Count == 1)
{
dteTry.ExecuteCommand(
"File.OpenFile",
String.Format("\"{0}\"", file));
}
}
bindCtx.ReleaseBoundObjects();
}
}
}
}
[DllImport("ole32.dll")]
public static extern int GetRunningObjectTable(int reserved,
out IRunningObjectTable prot);
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved,
out IBindCtx ppbc);
чтение фона: How to use Marshal.getActiveObject() to get 2 instance of of a running process that has two processes open
Что именно входит в переменный файл? – rene
«Something.CS» => Существующий файл C#. .CS ассоциируется с Visual Studio на моей системе –