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.