in vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAFileItem.cs [325:423]
private void DoSave(bool isCalledFromSaveAs, string fileName)
{
UIThread.DoOnUIThread(delegate() {
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
if (this.Node == null || this.Node.ProjectMgr == null || this.Node.ProjectMgr.IsClosed || this.Node.ProjectMgr.Site == null)
{
throw new InvalidOperationException();
}
IVsExtensibility3 extensibility = this.Node.ProjectMgr.Site.GetService(typeof(IVsExtensibility)) as IVsExtensibility3;
if (extensibility == null)
{
throw new InvalidOperationException();
}
extensibility.EnterAutomationFunction();
IntPtr docData = IntPtr.Zero;
try
{
IVsRunningDocumentTable rdt = this.Node.ProjectMgr.Site.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
Debug.Assert(rdt != null, " Could not get running document table from the services exposed by this project");
if (rdt == null)
{
throw new InvalidOperationException();
}
// First we see if someone else has opened the requested view of the file.
uint itemid;
IVsHierarchy ivsHierarchy;
uint docCookie;
IntPtr projectPtr = IntPtr.Zero;
int canceled;
string url = this.Node.Url;
ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, url, out ivsHierarchy, out itemid, out docData, out docCookie));
// If an empty file name is passed in for Save then make the file name the project name.
if (!isCalledFromSaveAs && fileName.Length == 0)
{
ErrorHandler.ThrowOnFailure(this.Node.ProjectMgr.SaveItem(VSSAVEFLAGS.VSSAVE_SilentSave, url, this.Node.ID, docData, out canceled));
}
else
{
Utilities.ValidateFileName(this.Node.ProjectMgr.Site, fileName);
// Compute the fullpath from the directory of the existing Url.
string fullPath = fileName;
if (!Path.IsPathRooted(fileName))
{
string directory = Path.GetDirectoryName(url);
fullPath = Path.Combine(directory, fileName);
}
if (!isCalledFromSaveAs)
{
if (!NativeMethods.IsSamePath(this.Node.Url, fullPath))
{
throw new InvalidOperationException();
}
ErrorHandler.ThrowOnFailure(this.Node.ProjectMgr.SaveItem(VSSAVEFLAGS.VSSAVE_SilentSave, fullPath, this.Node.ID, docData, out canceled));
}
else
{
ErrorHandler.ThrowOnFailure(this.Node.ProjectMgr.SaveItem(VSSAVEFLAGS.VSSAVE_SilentSave, fullPath, this.Node.ID, docData, out canceled));
}
}
if (canceled == 1)
{
throw new InvalidOperationException();
}
}
catch (COMException e)
{
throw new InvalidOperationException(e.Message);
}
finally
{
try
{
extensibility.ExitAutomationFunction();
}
finally
{
if (docData != IntPtr.Zero)
{
Marshal.Release(docData);
}
}
}
});
}