Compile a visual studio solution programmatically - msbuild

I have a requirement of programmatically compiling a solution. I cannot directly give the path of MSBuild because it differs between 2013 and earlier versions.
I am sharing my code below -
Using exeprocess As New System.Diagnostics.Process
exeprocess.StartInfo.FileName = "cmd"
exeprocess.StartInfo.CreateNoWindow = True
exeprocess.StartInfo.UseShellExecute = False
exeprocess.StartInfo.RedirectStandardInput = True
exeprocess.StartInfo.RedirectStandardOutput = True
exeprocess.Start()
Dim sw As StreamWriter = exeprocess.StandardInput
Dim sr As StreamReader = exeprocess.StandardOutput
sw.WriteLine("PUSHD C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\")
sw.WriteLine("call vcvarsall.bat")
sw.WriteLine("#MSBuild /t:Rebuild" & " /flp1:logfile=" & """" & logFilePath & """;errorsonly" & " " & """" & solutionPath & """")
sr.ReadLine()
While Not sr.EndOfStream()
sr.ReadLine()
End While
End Using
My requirement is to wait until the compilation is over.
The issue is that it hangs at the line "While Not sr.EndOfStream()".
I am unable to understand the reason for the issue. Not sure if this is the right way of ensuring that the compilation is over.
Any help is highly appreciated.

I can't tell what your specific problem is, but a few recommendations:
Don't bother writing to input stream, just generate a simple .bat text file and launch it.
You can use Microsoft.Build.Utilities.ToolLocationHelper to get any of the paths.
You can use Microsoft.Build.Execution.BuildManager to build programmatically.

Related

Get the path to an execuatble in vb.net?

I'm making a task manager type program and I need to get the path to every file. I don't want to find out the directory off my own executable. Just external files.
This is the beginning of getting the executable:
For Each OneProcess As Process In Process.GetProcesses
To find the directory and file name of any Process use MainModule.FileFileName
Here is sample code to help
System.Diagnostics.Process mm22= System.Diagnostics.Process.GetProcessesByName("notepad")[0];
string stp = mm22.MainModule.FileName; //location of the executable with filename
I had the same problem.. browse for answers, got close but it wasnt what i was excepting, then i saw GetProcessesByName which reminded me of javascript..so i changed it to GetProcessById.
For Each p In System.Diagnostics.Process.GetProcesses()
ListBox1.Items.Add(p.ProcessName & " - " & p.Id.ToString() & " - ")
Next
Dim id = ListBox1.SelectedItem.ToString.Split("-")(1).Trim
Dim p As System.Diagnostics.Process = System.Diagnostics.Process.GetProcessById(id)
MsgBox( p.MainModule.FileName)

Strange symbols stopping my batch file running in VB.net

I am trying to create and run a batch file from VB.net, then get the output and print it out. But when it runs it is appended by these symbols '´╗┐. Causing this error '´╗┐cd' is not recognized as an internal or external command, operable program or batch file. When I look at the batch file in notepad++ there is no symbol there! What is happening! Thanks James.
Code:
Dim path As String = Directory.GetCurrentDirectory()
Dim command As String = "cd " & path & " & " & argument
MsgBox(command)
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter(tempFile, False)
file.WriteLine("#ECHO OFF")
file.WriteLine(command)
file.Close()
Dim objProcess As New Process()
Dim SROutput As System.IO.StreamReader
With objProcess.StartInfo
.FileName = tempFile
.RedirectStandardOutput = True
.UseShellExecute = False
.Arguments = ""
End With
objProcess.Start()
SROutput = objProcess.StandardOutput
Do While SROutput.Peek <> -1
'MessageBox.Show(SROutput.ReadLine)
rtbOutput.Text = rtbOutput.Text & SROutput.ReadLine & vbNewLine
Loop
objProcess.Dispose()
'Process.Start(tempFile)
rtbOutput.Text = rtbOutput.Text & message & vbNewLine
That's a Byte Order Mark.
It means the OpenTextFileWriter() method is using a different encoding than you expect. You can fix the problem by using OpenTextFileWriter() overload that allows you pick an encoding like ASCII with no byte order mark or use the encoding with the byte order mark that matches what the DOS subsystem is expecting.
Solved, Im not entirely sure what was happening when it was writing the file, but I have changed it to this
Using writer As StreamWriter = New StreamWriter(tempFile)
writer.Write(command)
End Using
and its now running fine!. Thanks for any time spent on this and feel free to post an explination as to why this was happening.

killing process used by vb.net

I need some help with my program. I want to rewrite the data on my .txt file but an error occurs:
The process cannot access the file 'C:\Users\AARVIII\Documents\Visual Studio 2010\Projects\PROJECT\WindowsApplication3\bin\Debug\ORDERS\aa.txt' because it is being used by another process.
Here is the code:
Sub WRITEDATA()
Dim write As New System.IO.StreamWriter("ORDERS\" & TBFNAME.Text + "" + TBLNAME.Text & ".txt", False)
write.WriteLine(TBFNAME.Text)
write.WriteLine(TBLNAME.Text)
write.WriteLine(TBEADD.Text)
write.WriteLine(TBEADD2.Text)
write.WriteLine(TBADDRESS.Text)
write.WriteLine(TBCONTACT.Text)
write.close()
End Sub
I used a StreamReader to get the data which had already been put in that text file. Please help me figure out how to kill that process so that I can rewrite my data.
It is very possible that your app (on another thread?) is the culprit. First, to make sure you release the resource, make sure to wrap your code in a using block:
Using Dim write As New System.IO.StreamWriter("ORDERS\" & TBFNAME.Text + "" + TBLNAME.Text & ".txt", False)
write.WriteLine(TBFNAME.Text)
write.WriteLine(TBLNAME.Text)
write.WriteLine(TBEADD.Text)
write.WriteLine(TBEADD2.Text)
write.WriteLine(TBADDRESS.Text)
write.WriteLine(TBCONTACT.Text)
End Using
Additionally, you may want to see this thread: .NET Asynchronous stream read/write

Issue with an LPR Command in VB

I am creating a VB app which will "move" xls reports from a directory to a ReportSafe app. I am also working in an existing VB app which does just that, so I am using it for reference.
It isn't as simple as moving files from one directory to another, because ReportSafe requires an lpr command to tell it (ReportSafe) which file to pick up.
Here is what I have so far:
Imports System.IO
Module Module1
Sub Main()
''Declarations
Dim Files As ArrayList = New ArrayList()
Dim FileName As String
''Write All Files in *directory* to ReportSafe
Files.Clear()
Files.AddRange(Directory.GetFiles(*directory*))
For Each FileName In Files
Dim RPname As String
Dim RealName As String
RPname = FileName.ToString
RealName = "/"
RealName = RealName & RPname.Remove(0, 34)
Dim a As New Process
a.StartInfo.FileName = "C:\Windows\system32\lpr.exe"
a.StartInfo.Arguments = "-S*ServerName* -Plp -J" & Chr(34) & RealName & Chr(34) & " " & Chr(34) & RPname & Chr(34)
a.StartInfo.UseShellExecute = False
Next
End Sub
End Module
The whole lpr command/arguments are throwing me for a loop. I'm not sure if my question is specific to ReportSafe, and if that's the case, I may be out of luck here. I have pulled this code from the already existing app which moves reports to ReportSafe, and adjusted for my own use, but no luck so far.
FYI, I had to turn on LPR Monitor services to obtain to the lpr.exe
Questions:
What are the proper arguments to pass through to this lpr command?
Is there a problem with the logic that is causing the issue?
I continued to tinker and look at my reference code and discovered some flaws in logic:
For one, the report name I was passing did not include the complete file path.
Another thing is that I never started the process with a.Start(). Rookie mistakes for sure... haha

How do I customize the auto commenting text in Visual Studio?

When I type the trigger the auto comment feature in Visual Studio (by typing "'''" or "///"), most of the XML commenting details show up that I like. However, I typically add the history tag to the documentation so I can track and changes that are made to the method over time.
Is there any way I can customize the auto commenting feature so that it will add the history tag, and potentially some generic Name - Date - Change placeholder text?
I'd suggest using GhostDoc. It generates very smart comments using /// based on your method names and parameters. Also, it is fully customizable.
I think that you could use a tool as dgarcia said but try to chose one that makes the version control insetad, Personally I'm not a huge fan of keep the "history" or track of the project using comments in the code.
If you like that way you could create your own customized version of the snippet, this is easier if you use a tool like Snippy
Copy this file to your
My Documents\Visual Studio 2005\Code Snippets[Language]\My Code Snippets\
Just be carefull to change the file if you gonna use it in VB.NET
Hope this help
Just as followup to the comment to Olivier. Here is a copy of the macro now, look for the '' Do History section to see where I inserted code.
''// InsertDocComments goes through the current document using the VS Code Model
''// to add documentation style comments to each function.
''
Sub InsertDocComments()
Dim projectItem As ProjectItem
Dim fileCodeModel As FileCodeModel
Dim codeElement As CodeElement
Dim codeElementType As CodeType
Dim editPoint As EditPoint
Dim commentStart As String
projectItem = DTE.ActiveDocument.ProjectItem
fileCodeModel = projectItem.FileCodeModel
codeElement = fileCodeModel.CodeElements.Item(1)
''// For the sample, don't bother recursively descending all code like
''// the OutlineCode sample does. Just get a first CodeType in the
''// file.
If (TypeOf codeElement Is CodeNamespace) Then
codeElement = codeElement.members.item(1)
End If
If (TypeOf codeElement Is CodeType) Then
codeElementType = CType(codeElement, CodeType)
Else
Throw New Exception("Didn't find a type definition as first thing in file or find a namespace as the first thing with a type inside the namespace.")
End If
editPoint = codeElementType.GetStartPoint(vsCMPart.vsCMPartHeader).CreateEditPoint()
''// Make doc comment start.
commentStart = LineOrientedCommentStart()
If (commentStart.Length = 2) Then
commentStart = commentStart & commentStart.Chars(1) & " "
ElseIf (commentStart.Length = 1) Then
commentStart = commentStart & commentStart.Chars(0) & commentStart.Chars(0) & " "
End If
''// Make this atomically undo'able. Use Try...Finally to ensure Undo
''// Context is close.
Try
DTE.UndoContext.Open("Insert Doc Comments")
''// Iterate over code elements emitting doc comments for functions.
For Each codeElement In codeElementType.Members
If (codeElement.Kind = vsCMElement.vsCMElementFunction) Then
''// Get Params.
Dim parameters As CodeElements
Dim codeFunction As CodeFunction
Dim codeElement2 As CodeElement
Dim codeParameter As CodeParameter
codeFunction = codeElement
editPoint.MoveToPoint(codeFunction.GetStartPoint(vsCMPart.vsCMPartHeader))
''//editPoint.LineUp()
parameters = codeFunction.Parameters
''// Do comment.
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.LineUp()
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart & "<summary>")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart & "Summary of " & codeElement.Name & ".")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart & "</summary>")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart)
For Each codeElement2 In parameters
codeParameter = codeElement2
editPoint.Insert("<param name=" & codeParameter.Name & "></param>")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart)
Next ''//param
''// Do history tag.
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.LineUp()
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart & "<history>")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart & "Name MM/DD/YYYY [Created]")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart & "</history>")
editPoint.Insert(Microsoft.VisualBasic.Constants.vbCrLf)
editPoint.Insert(Microsoft.VisualBasic.Constants.vbTab & commentStart)
End If ''//we have a function
Next ''//code elt member
Finally
DTE.UndoContext.Close()
End Try
End Sub
For some reason, after a save, rebuild, and a restart of Visual Studio, I'm not getting the history tag. Can anybody see something here I'm missing?
vb uses a xml file to load the defults. It is VBXMLDoc.xml and it depends on what version you are running as to the location of the file.