Visual Studio exposes exactly the same “Window → New Window” feature you use by hand through the VS SDK:
step | API | what it does |
---|---|---|
① | IVsUIShellOpenDocument.OpenCopyOfStandardEditor | creates the “file:2” clone of an existing IVsWindowFrame (that is the programmatic equivalent of New Window) |
① | IVsUIShellOpenDocument.OpenCopyOfStandardEditor | creates the “file:2” clone of an existing IVsWindowFrame (that is the programmatic equivalent of New Window) |
② | Window.Activate / DTE.ExecuteCommand("Window.MoveToNextTabGroup")(or …PreviousTabGroup, …MainDocumentGroup) | moves the active document tab into any other document-group, exactly the way the built-in menu items Window → Move to Next Tab Group / Previous Tab Group do |
// async package suggested – avoids blocking the UI thread
public async Task DuplicateIntoOtherGroupAsync(IVsWindowFrame sourceFrame)
{
// 1. clone the document (New Window)
var openDoc = await AsyncServiceProvider.GlobalProvider
.GetServiceAsync(typeof(SVsUIShellOpenDocument))
as IVsUIShellOpenDocument;
Guid logicalView = VSConstants.LOGVIEWID_Primary; // normal text view
IVsWindowFrame cloneFrame;
ErrorHandler.ThrowOnFailure(
openDoc.OpenCopyOfStandardEditor(sourceFrame, ref logicalView, out cloneFrame));
// 2. show the new frame and obtain the EnvDTE.Window wrapper
cloneFrame.Show();
cloneFrame.GetProperty((int)__VSFPROPID.VSFPROPID_ExtWindowObject, out object winObj);
var dteWin = (EnvDTE.Window)winObj;
// 3. move it to the other document group
dteWin.Activate(); // becomes the active tab
var dte = (EnvDTE80.DTE2)Package.GetGlobalService(typeof(SDTE));
dte.ExecuteCommand("Window.MoveToNextTabGroup");
}
Duplicate – OpenCopyOfStandardEditor gives you the brand-new IVsWindowFrame (main.cpp:2, etc.).
Relocate – activating that frame and firing the built-in command moves it to the neighbour group; if you want the group on the left instead of the right, use Window.MoveToPreviousTabGroup, or send the command twice to hop across several groups.
Because you are executing the same IDE commands the UI uses, you don’t have to worry about low-level frame layout APIs, persistence, or edge-cases—Visual Studio handles all of that for you.