示例#1
0
        private static string GetFilenameFromOutput(IVsOutput2 output)
        {
            object propVal;
            int    hr;

            try
            {
                hr = output.get_Property("OUTPUTLOC", out propVal);
            }
            catch (Exception ex)
            {
                hr      = Marshal.GetHRForException(ex);
                propVal = null;
            }
            var path = propVal as string;

            if (ErrorHandler.Succeeded(hr) && !string.IsNullOrEmpty(path))
            {
                return(path);
            }

            ErrorHandler.ThrowOnFailure(output.get_DeploySourceURL(out path));
            return(new Uri(path).LocalPath);
        }
示例#2
0
        private static string GetFilenameFromOutput(IVsOutput2 output) {
            object propVal;
            int hr;
            try {
                hr = output.get_Property("OUTPUTLOC", out propVal);
            } catch (Exception ex) {
                hr = Marshal.GetHRForException(ex);
                propVal = null;
            }
            var path = propVal as string;
            if (ErrorHandler.Succeeded(hr) && !string.IsNullOrEmpty(path)) {
                return path;
            }

            ErrorHandler.ThrowOnFailure(output.get_DeploySourceURL(out path));
            return new Uri(path).LocalPath;
        }
示例#3
0
        /// <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);
            }
        }