Every couple of weeks, I'll get a question about getting an arbitrary file on disk into a project in VS without asking VS to open in a document window directly. It seems to be pretty hard to find information for (when I needed to do it, it took a few email threads with various other teams to figure it out), so here's a code snippet I use for this. It works by adding the file to the miscellaneous files project (if it isn't already in another project) and then returning the hierarchy/itemid for the file, which can be used with other methods involving the shell, opening documents, locking documents, etc.


/// <summary>
/// If the given file isn't in a project, put it in the miscellaneous files project, and return
/// the project/itemid of the file.
/// </summary>
/// <returns>hresult (failure code)</returns>
static int EnsureFileInAProject(string fileName, out IVsUIHierarchy hierarchy, out uint itemId)
{
    IVsUIShellOpenDocument shellOpenDocument = ServiceProvider.GlobalProvider.GetService(typeof(SVsUIShellOpenDocument)) as IVsUIShellOpenDocument;

    IOleServiceProvider unused;
    int pDocInAProject;

    // Before we can take a lock, we need to make sure the given doc data is in a project.

    // First, ask the shell if it already is
    if (ErrorHandler.Failed(shellOpenDocument.IsDocumentInAProject(fileName, out hierarchy, out itemId, out unused, out pDocInAProject)))
    {
        Debug.Fail("IsDocumentInAProject failed, which is unexpected.");
        return VSConstants.E_FAIL;
    }

    // We need to add it to the miscellaneous files project if it isn't in a project.
    if (pDocInAProject == (int)__VSDOCINPROJECT.DOCINPROJ_DocNotInProject)
    {
        var externalFilesManager = Shell.Package.GetGlobalService(typeof(SVsExternalFilesManager)) as IVsExternalFilesManager;
        if (externalFilesManager == null)
        {
            Debug.Fail("Can't find the miscellaneous files project to use.");
            return VSConstants.E_FAIL;
        }

        // Make sure the misc files project doesn't actually *open* the document
        uint createFlags = (uint)__VSCREATEDOCWIN.CDW_RDTFLAGS_MASK | (uint)_VSRDTFLAGS.RDT_PlaceHolderDoc;
        Guid emptyGuid = Guid.Empty;
        int unusedPos;
        IVsWindowFrame unusedFrame;

        if (ErrorHandler.Failed(externalFilesManager.AddDocument(createFlags, fileName, IntPtr.Zero, IntPtr.Zero, ref emptyGuid, null, ref emptyGuid, null, null, out unusedPos, out unusedFrame)))
        {
            Debug.Fail("Couldn't add the document to miscellaneous files project.");
            return VSConstants.E_FAIL;
        }

        IVsProject miscProject;
        if (ErrorHandler.Failed(externalFilesManager.GetExternalFilesProject(out miscProject)) ||
            (hierarchy = miscProject as IVsUIHierarchy) == null ||
            ErrorHandler.Failed(hierarchy.ParseCanonicalName(fileName, out itemId)))
        {
            Debug.Fail("Couldn't get the misc files project or item we just added.");
            return VSConstants.E_FAIL;
        }
    }

    return VSConstants.S_OK;
}