Python function for building .NET 2003 Solutions

D

David Blume

I'm very grateful to Roger Burnham for his Visual Studio 6.0 build
script listed here:
http://mail.python.org/pipermail/python-list/2001-December/076881.html

Now that I'm building projects in .NET 2003, I thought I'd post an
update to his DoBuild() function that does the same thing with
Solutions. Note the differences:

1. Instead of having a RebuildAll() function, we have to Clean() then
Build(). This function does the cleaning of all the targets in one
pass, then the building of all the targets, in case some targets share
dependencies.
2. On a compile-time error, instead of raising SystemExit, which is
much cleaner, this script returns the BuildLog.htm of the component
that failed. (Which may not have been the target that was built, but
a sub-project.) I didn't really know how to determine exactly which
subproject failed, so I parse the contents of the output window to
find it. (VC6 is much easier, the .plg file showed the build status
of the target and all its dependencies.)

Anyway, here's BuildSolution() with similar parameters as Roger's
DoBuild(). Please fix any line-wrapping errors that have occurred
between my sending of the post and your reception of it. Sorry about
those.

import win32com.client.dynamic
import string
import pywintypes
import win32clipboard
import win32con

def BuildSolution(VC, solution, projectList, configSuffix, force):
"""Build Visual C++ 7.1 Solutions

returns None if successful, or the build log if
there were compile time errors."""
if VC is None:
VC = win32com.client.Dispatch('VisualStudio.DTE')
VC.MainWindow.Visible = True
VCDocs = VC.Documents
VCDocs.CloseAll(3)

sln = VC.Solution
sln.Open(solution)
slnBuild = sln.SolutionBuild
tailLen = len(configSuffix)
# First, clean everything if doing a forced rebuild
if force:
for projectName in projectList:
for project in sln.Projects:
if str(project.Name) == projectName:
for config in slnBuild.SolutionConfigurations:
name = str(config.Name)
if name[-tailLen:] == configSuffix:
for context in config.SolutionContexts:
if projectName + "." in context.ProjectName:
context.ShouldBuild = True
break
break
slnBuild.Clean(True)
# Then, build the specified projects
for projectName in projectList:
projFound = 0
for project in sln.Projects:
if str(project.Name) == projectName:
projFound = 1
for config in slnBuild.SolutionConfigurations:
confFound = 0
name = str(config.Name)
if name[-tailLen:] == configSuffix:
confFound = 1
slnBuild.BuildProject(config.Name, project.UniqueName,
True)
if slnBuild.BuildState == 3:
if slnBuild.LastBuildInfo != 0:
print 'There were', slnBuild.LastBuildInfo, 'errors
building', projectName + '.\n'
# We have to jump through some hoops to determine
which
# subproject actually failed, because the BuildLog.htm
# associated with this target does not reflect the
# compiled state of the subprojects.Here's what we do:
# 1. Obtain the OutputWindow from MSDev.
# 2. Copy the text to the clipboard, and extract that
# into a "lines" array.
# 3. Search for lines containing the word "error" and
# assume that's the first failed project.
# 4. Extract and return the filename of the
# BuildLog.htm for the assumed failed project.
outputPane =
VC.Windows.Item('{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}').Object.ActivePane
# vsWindowKindOutput
outputPane.TextDocument.Selection.SelectAll()
outputPane.TextDocument.Selection.Copy()
outputPane = None
win32clipboard.OpenClipboard(0)
lines =
win32clipboard.GetClipboardData(win32con.CF_TEXT)
win32clipboard.CloseClipboard()
bFoundErrorMessages = False
LogfileString = "Build log was saved at \"file://"
for line in string.split(lines, "\n"):
if not bFoundErrorMessages and line.find(" : error
") != -1:
print "This is the first error:"
print line + "\n"
bFoundErrorMessages = True
if bFoundErrorMessages and
line.startswith(LogfileString):
return line[len(LogfileString):line.rfind('"')]
raise "Could not locate the failing project's
logfile."
else:
raise "BuildProject is returning asynchronously!"
break
if not confFound:
print 'Build failed: Could not find the', configSuffix,
'for', projectName + '.'
break
if not projFound:
print 'Build failed: Could not find the project', projectName +
'.'
return None
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top