/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Apache License, Version 2.0. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Apache License, Version 2.0, please send an email to * vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Apache License, Version 2.0. * * You must not remove this notice, or any other, from this software. * * ***************************************************************************/ using System; using System.Diagnostics; using System.IO; using Microsoft.Build.Execution; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.Project { class Output : IVsOutput2 { private ProjectNode project; private ProjectItemInstance output; /// /// Constructor for IVSOutput2 implementation /// /// Project that produce this output /// MSBuild generated item corresponding to the output assembly (by default, these would be of type MainAssembly public Output(ProjectNode projectManager, ProjectItemInstance outputAssembly) { VsUtilities.ArgumentNotNull("projectManager", projectManager); project = projectManager; output = outputAssembly; } #region IVsOutput2 Members public int get_CanonicalName(out string pbstrCanonicalName) { if (output == null) { pbstrCanonicalName = project.Url; return VSConstants.S_OK; } // Get the output assembly path (including the name) pbstrCanonicalName = output.GetMetadataValue("FullPath"); Debug.Assert(!String.IsNullOrEmpty(pbstrCanonicalName), "Output Assembly not defined"); // Make sure we have a full path pbstrCanonicalName = CommonUtils.GetAbsoluteFilePath(project.ProjectHome, pbstrCanonicalName); return VSConstants.S_OK; } /// /// This path must start with file:/// if it wants other project /// to be able to reference the output on disk. /// If the output is not on disk, then this requirement does not /// apply as other projects probably don't know how to access it. /// public virtual int get_DeploySourceURL(out string pbstrDeploySourceURL) { if (output == null) { // we're lying here to keep callers happy who expect a path... See also OutputGroup.get_KeyOutputObject pbstrDeploySourceURL = GetType().Assembly.CodeBase; return VSConstants.S_OK; } string path = output.GetMetadataValue(ProjectFileConstants.FinalOutputPath); if (string.IsNullOrEmpty(path)) { pbstrDeploySourceURL = new Url(output.GetMetadataValue("FullPath")).Uri.AbsoluteUri; return VSConstants.S_OK; } if (path.Length < 9 || String.Compare(path.Substring(0, 8), "file:///", StringComparison.OrdinalIgnoreCase) != 0) path = "file:///" + path; pbstrDeploySourceURL = path; return VSConstants.S_OK; } public int get_DisplayName(out string pbstrDisplayName) { return this.get_CanonicalName(out pbstrDisplayName); } public virtual int get_Property(string szProperty, out object pvar) { if (output == null) { pvar = null; return VSConstants.E_NOTIMPL; } String value = output.GetMetadataValue(szProperty); pvar = value; // If we don't have a value, we are expected to return unimplemented return String.IsNullOrEmpty(value) ? VSConstants.E_NOTIMPL : VSConstants.S_OK; } // TODO: Should RootRelativeURL be based on ProjectHome? public int get_RootRelativeURL(out string pbstrRelativePath) { if (output == null) { pbstrRelativePath = Path.GetDirectoryName(project.Url); return VSConstants.E_FAIL; } pbstrRelativePath = String.Empty; object variant; // get the corresponding property if (ErrorHandler.Succeeded(this.get_Property("TargetPath", out variant))) { string var = variant as String; if (var != null) { pbstrRelativePath = var; } } else { string baseDir = output.Project.Directory; string fullPath = output.GetMetadataValue("FullPath"); if (CommonUtils.IsSubpathOf(baseDir, fullPath)) { // TODO: Maybe GetRelativeFilePath? pbstrRelativePath = CommonUtils.GetRelativeDirectoryPath(baseDir, fullPath); } } return VSConstants.S_OK; } public virtual int get_Type(out Guid pguidType) { pguidType = Guid.Empty; throw new NotImplementedException(); } #endregion } }