in vsintegration/src/FSharp.ProjectSystem.Base/Project/FileNode.cs [932:1015]
public bool RenameDocument(string oldName, string newName)
{
IVsRunningDocumentTable pRDT = this.GetService(typeof(IVsRunningDocumentTable)) as IVsRunningDocumentTable;
if (pRDT == null) return false;
IntPtr docData = IntPtr.Zero;
IVsHierarchy pIVsHierarchy;
uint itemId;
uint uiVsDocCookie;
SuspendFileChanges sfc = new SuspendFileChanges(this.ProjectMgr.Site, oldName);
sfc.Suspend();
try
{
VSRENAMEFILEFLAGS renameflag = VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags;
ErrorHandler.ThrowOnFailure(pRDT.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, oldName, out pIVsHierarchy, out itemId, out docData, out uiVsDocCookie));
if (pIVsHierarchy != null && !Utilities.IsSameComObject(pIVsHierarchy, this.ProjectMgr))
{
// Don't rename it if it wasn't opened by us.
return false;
}
// ask other potentially running packages
if (!this.ProjectMgr.Tracker.CanRenameItem(oldName, newName, renameflag))
{
return false;
}
// Allow the user to "fix" the project by renaming the item in the hierarchy
// to the real name of the file on disk.
bool shouldRenameInStorage = IsFileOnDisk(oldName) || !IsFileOnDisk(newName);
Transactional.Try(
// Action
() => { if (shouldRenameInStorage) RenameInStorage(oldName, newName); },
// Compensation
() => { if (shouldRenameInStorage) RenameInStorage(newName, oldName); },
// Continuation
() =>
{
string newFileName = Path.GetFileName(newName);
string oldCaption = this.Caption;
Transactional.Try(
// Action
() => DocumentManager.UpdateCaption(this.ProjectMgr.Site, newFileName, docData),
// Compensation
() => DocumentManager.UpdateCaption(this.ProjectMgr.Site, oldCaption, docData),
// Continuation
() =>
{
bool caseOnlyChange = NativeMethods.IsSamePath(oldName, newName);
if (!caseOnlyChange)
{
// Check out the project file if necessary.
if (!this.ProjectMgr.QueryEditProjectFile(false))
{
throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
}
this.RenameFileNode(oldName, newName);
}
else
{
this.RenameCaseOnlyChange(newFileName);
}
bool extensionWasChanged = (0 != String.Compare(Path.GetExtension(oldName), Path.GetExtension(newName), StringComparison.OrdinalIgnoreCase));
if (extensionWasChanged)
{
// Update the BuildAction
this.ItemNode.ItemName = this.ProjectMgr.DefaultBuildAction(newName);
}
this.ProjectMgr.Tracker.OnItemRenamed(oldName, newName, renameflag);
});
});
}
finally
{
if (docData != IntPtr.Zero)
{
Marshal.Release(docData);
}
sfc.Resume(); // can throw, e.g. when RenameFileNode failed, but file was renamed on disk and now editor cannot find file
}
return true;
}