public int OpenOutputGroup(string szCanonicalName, out IVsOutputGroup ppIVsOutputGroup) { IVsProjectCfg2 projCfg = _pythonCfg as IVsProjectCfg2; if (projCfg != null) { return(projCfg.OpenOutputGroup(szCanonicalName, out ppIVsOutputGroup)); } ppIVsOutputGroup = null; return(VSConstants.E_NOTIMPL); }
/// <summary> /// Gets the variables and directories for the specified project. Variables will be in /// the form <c>ProjectName.VariableName</c>. /// </summary> /// <param name="variables">The <see cref="NameValueCollection"/> to add the variables to.</param> /// <param name="hierarchy">The <see cref="IVsHierarchy"/> (project) from which to retrieve the variables.</param> private void GetTargetVariables(NameValueCollection variables, IVsHierarchy hierarchy, string projectPrefix) { try { int hr = NativeMethods.S_OK; // Now we need to get a IVsProjectCfg2 object to get the TargetX variables. We do this // by querying the environment for the active configuration of the specified project. IVsSolutionBuildManager solutionBuildManager = Package.Instance.GetService(typeof(IVsSolutionBuildManager)) as IVsSolutionBuildManager; if (solutionBuildManager == null) { Tracer.WriteLine(classType, "GetTargetVariables", Tracer.Level.Warning, "Cannot get an instance of IVsSolutionBuildManager from the environment. Skipping the project's TargetX variables."); return; } IVsProjectCfg[] projectCfgArray = new IVsProjectCfg[1]; hr = solutionBuildManager.FindActiveProjectCfg(IntPtr.Zero, IntPtr.Zero, hierarchy, projectCfgArray); if (NativeMethods.Failed(hr)) { Tracer.WriteLineWarning(classType, "GetTargetVariables", "One of the projects in the solution does not support project configurations. Skipping the project's TargetX variables."); return; } IVsProjectCfg2 projectCfg2 = projectCfgArray[0] as IVsProjectCfg2; if (projectCfg2 == null) { Tracer.WriteLine(classType, "GetTargetVariables", Tracer.Level.Warning, "The IVsSolutionBuildManager.FindActiveProjectCfg returned a null object or an object that doesn't support IVsProjectCfg2. Skipping the project's TargetX variables."); return; } // Get the ConfigurationName and add it to the variables. string configurationName; NativeMethods.ThrowOnFailure(projectCfg2.get_DisplayName(out configurationName)); variables.Add(projectPrefix + "ConfigurationName", configurationName); // We need to get the Built output group from the list of project output groups. IVsOutputGroup outputGroup; NativeMethods.ThrowOnFailure(projectCfg2.OpenOutputGroup("Built", out outputGroup)); if (outputGroup == null) { Tracer.WriteLine(classType, "GetTargetVariables", Tracer.Level.Warning, "The project configuration '{0}' does not support the 'Built' output group. Skipping the TargetX variables.", configurationName); return; } // Get the key output canonical name from the Built output group. string keyOutputCanonicalName; NativeMethods.ThrowOnFailure(outputGroup.get_KeyOutput(out keyOutputCanonicalName)); // Search through the outputs until we find the key output. We have to call get_Outputs // twice: once to get the number of outputs (we do this by passing in 0 as the number // requested), and then once to get the actual outputs. uint numberRequested = 0; IVsOutput2[] outputArray = new IVsOutput2[numberRequested]; uint[] numberFetchedArray = new uint[1]; NativeMethods.ThrowOnFailure(outputGroup.get_Outputs(numberRequested, outputArray, numberFetchedArray)); // We should have the number of elements in the output array now, so get them. numberRequested = numberFetchedArray[0]; outputArray = new IVsOutput2[numberRequested]; NativeMethods.ThrowOnFailure(outputGroup.get_Outputs(numberRequested, outputArray, numberFetchedArray)); IVsOutput2 keyOutput = null; for (int i = 0; i < numberFetchedArray[0]; i++) { if (outputArray.Length <= i) { break; } IVsOutput2 output = outputArray[i]; string outputCanonicalName; NativeMethods.ThrowOnFailure(output.get_CanonicalName(out outputCanonicalName)); if (outputCanonicalName == keyOutputCanonicalName) { keyOutput = output; break; } } // Check to make sure that we found the key output. if (keyOutput == null) { Tracer.WriteLine(classType, "GetTargetVariables", Tracer.Level.Warning, "We identified the key output from configuration '{0}' as '{1}', but when we iterated through the outputs we couldn't find the key output. Skipping the TargetX variables.", configurationName, keyOutputCanonicalName); return; } // Now that we have the key output, we can finally create the TargetX variables from // the key output's deploy source URL. string deploySourceUrl; NativeMethods.ThrowOnFailure(keyOutput.get_DeploySourceURL(out deploySourceUrl)); // By convention, the deploy source URL starts with file:/// for file-based outputs. // Strip it off if it's there. if (deploySourceUrl.StartsWith("file:///")) { deploySourceUrl = deploySourceUrl.Substring("file:///".Length); } // Parse the TargetX variables from the deploy source URL. string targetPath = deploySourceUrl; string targetFileName = Path.GetFileName(targetPath); string targetDosFileName = this.EncodeDosFileName(targetFileName); string targetName = Path.GetFileNameWithoutExtension(targetFileName); string targetExt = PackageUtility.EnsureLeadingChar(Path.GetExtension(targetPath), '.'); string targetDir = PackageUtility.StripTrailingChar(Path.GetDirectoryName(targetPath), Path.DirectorySeparatorChar); // Add the TargetX variables to the collection. variables.Add(projectPrefix + "TargetDir", targetDir); variables.Add(projectPrefix + "TargetDosFileName", targetDosFileName); variables.Add(projectPrefix + "TargetExt", targetExt); variables.Add(projectPrefix + "TargetFileName", targetFileName); variables.Add(projectPrefix + "TargetName", targetName); variables.Add(projectPrefix + "TargetPath", targetPath); } catch (Exception e) { if (ErrorUtility.IsExceptionUnrecoverable(e)) { throw; } Tracer.WriteLineWarning(classType, "GetTargetVariables", "The project does not correctly implement all of its required IVsProjectCfg2 interfaces. Skipping the TargetX variables. Exception: {0}", e); } }