Product Feedback woes and yet another macro


A while back, we received a suggestion via our product feedback website. The site lets anyone log bugs and/or suggestions for our product, which feed directly into our internal bug tracking mechanism. In other words, the site is not simply a façade but a direct input into our development, supplementing our internal testing (it’s hard to find every bug in a piece of code as large as Visual Studio) and helping us prioritize issues.


The upside of this website is that we have received valuable feedback, fixed real customer bugs (many of these fixes will be in our upcoming service pack) and identified certain features that are lacking and others that are slowly becoming superfluous. For example, many users voted on the fact that we lack support for code snippets in C++, a feature I would love to have and we are investigating providing this support in Orcas (our next release). When so many customers show their desire for the feature, it helps us allocate resources, something which is always in scarce supply


The downside of the product feedback is the simple fact that we can’t handle the quantity of bugs and suggestions that people submit (my personal opinion) and we’ve had to make some tough decisions with prioritization. While we fight to keep our product bug-free, we also understand the inescapable need to implement our customers’ suggestions. It’s one of the most simultaneously loathsome and attractive aspects of being a program manager at Microsoft. After all, few people in the industry can say they decide whether some feature will make it into a product used by millions


All this rambling has me straying from this post’s purpose. Yet another piece of (macro) code. Today’s macro was inspired by a suggestion we received via product feedback, which I deemed unworthy due to how easy it is to add using our extensibility model. Without further ado, here is a macro to preprocess the current file and bring it up in the editor.


 


    Sub RunPreprocessor()


 


        Dim doc As Document = DTE.ActiveDocument


        Dim docname As String = doc.Name.ToLower


        Dim project As Project = doc.ProjectItem.ContainingProject


 


        If doc.Language = “C/C++” Then


            ‘ not the most accurate way of identifying a cpp file


            If docname.EndsWith(“.cpp”) Then


 


                Dim vcproj As VCProject = project.Object


                Dim projfiles As IVCCollection = vcproj.Files


                Dim vcfile As VCFile = Nothing


 


                ‘ find the file in current project


                For Each f As VCFile In projfiles


                    If f.Name = doc.Name Then


                        vcfile = f


                        Exit For


                    End If


                Next


 


                Dim activeconfigname As String = DTE.Solution.SolutionBuild.ActiveConfiguration.Name


                Dim fileconfig As VCFileConfiguration = vcfile.FileConfigurations(activeconfigname)


                Dim filecompiler As VCCLCompilerTool = fileconfig.Tool


 


                ‘ toggle preprocessing on, compile, toggle preprocessing


                filecompiler.GeneratePreprocessedFile = preprocessOption.preprocessNoLineNumbers


                fileconfig.Compile(True, True)


                filecompiler.GeneratePreprocessedFile = preprocessOption.preprocessNo


 


                Dim preprocessedpath = doc.Path + docname.Replace(“.cpp”, “.i”)


                ClearEmptyLines(preprocessedpath)


                DTE.ItemOperations.OpenFile(preprocessedpath + “.cpp”)


 


            End If


        End If


 


    End Sub



And the required helper function:


    Sub ClearEmptyLines(ByVal filepath As String)


        Dim line As String


 


        ‘ iterate through a file and write out non-empty lines into a new file


        Using sr As New IO.StreamReader(filepath)


            ‘ out file name is <filename>.i.cpp (for highlighting)


            Using sw As New IO.StreamWriter(New IO.FileStream(filepath + “.cpp”, IO.FileMode.Create))


                While Not sr.EndOfStream


                    line = sr.ReadLine()


                    If line.Length > 0 Then


                        sw.WriteLine(line)


                    End If


                End While


            End Using


        End Using


    End Sub


The implementation has two issues in its current form. The first is that changing the compiler property on the file causes the project file to change, which in turn requires checking out the project file and probably re-linking the project. The second is that the macro always rebuilds the preprocessed file even when there is no need to. I will post a follow-up, solving both of these issues.

Comments (1)

  1. Anonymous says:

    I can’t seem to get this to work for me. When I run RunPreprocessor(), I get an error that filecompiler "is not set to an instance of an object."

    Things that I can think of that might be relevant are that the file has no file-specific customization, and that inherited project sheets are in use.

    I verified that activeconfigname was indeed the name of the active project, vcfile.Name was the name of the file, and that the file is compiled in that configuration (and all other configurations).

    Any ideas? This macro implements one of the features that I really miss from when emacs was my IDE.

    Thank you,

    Todd