运行环境: visual studio .net
介绍
我们每一个从原有的开发环境转移到vs.net下的用户,都遭遇到不少的阻碍.我所碰到的一个障碍就是:我原有的那些macro无法继续工作了.
现在的这个编译序列号自动增长工具是从很多人的代码片断组合而成的,虽然它并不完善,而且缺乏一些特性,但它至少为进一步开发提供了一个坚实的基础.
目标
这里是自动编译序列号的需求:
1. 在每一次release编译的时候,自动增加保存在一个单独文件中的编译序列号,这个文件将被加入到我的项目中.
2. 自动记录编译的日期和序列号.
代码分析
我的第一个任务是找到一个能够替代vs 6中.application_beforebuildstart()的事件,vs.net的设计者为我们提供了非常容易使用的编译事件:
onbuildbegin
onbuilddone
onbuildprojconfigbegin
onbuildprojconfigdone
这些事件句柄的命名规则有一点误导.我们不希望使用onbuildbegin,因为即使我们同时针对多种配置(release, debug等等)进行编译,它也只会被执行一次.这使得难以只在编译release版本的时候增加编译序列号.onbuildprojconfigbegin就能够在针对每一种配置编译的时候被执行,并且还提供一个名为projectconfig的字符串参数来描述当前所进行的编译使用的是哪一种配置.
大部分的任务是在onbuildprojconfigbegin事件处理函数中完成的, 它还使用了两个辅助macro:
writetologfile
writetooutputbuildpane
这两个宏都可以被写入到onbuildprojconfigbegin事件处理函数中,或者在不用时删除.
代码
' ------------------------------------
' onbuildprojconfigbegin event handler
' ------------------------------------
private sub buildevents_onbuildprojconfigbegin(
byval project as string,
byval projectconfig as string,
byval platform as string,
byval solutionconfig as string)
handles buildevents.onbuildprojconfigbegin
' abort if build type is debug
if instr(1, projectconfig, "debug", 1) then exit sub
' get ver filename
dim res_filename as string
res_filename = dte.solution.fullname
res_filename = path.changeextension(res_filename, ".ver")
' open version file and increment build number
dim msg_text as string
if file.exists(res_filename) then
dim line as string
try
dim sr as streamreader = new streamreader(res_filename)
line = sr.readline()
sr.close()
catch ex as exception
module1.writetooutputbuildpane(vbcrlf & _
"version file read failed : " &
ex.message & vbcrlf)
end try
line = right(line, line.length - 18)
try
dim sw as streamwriter = file.createtext(res_filename)
sw.writeline("#define build_num {0}", line + 1)
sw.close()
catch ex as exception
module1.writetooutputbuildpane(vbcrlf & _
"version file write failed : " &
ex.message & vbcrlf)
end try
msg_text = "build number : " & line + 1 & ", " & now
module1.writetooutputbuildpane(vbcrlf & msg_text & vbcrlf)
module1.writetologfile(msg_text)
else
try
dim sw as streamwriter = file.createtext(res_filename)
sw.writeline("#define build_num 1")
sw.close()
catch ex as exception
module1.writetooutputbuildpane(vbcrlf & _
"version file write failed : " &
ex.message & vbcrlf)
end try
msg_text = "build number : 1, " & now
module1.writetooutputbuildpane(vbcrlf & msg_text & vbcrlf)
module1.writetologfile(msg_text)
end if
end sub
' ----------------------------------
' write text message to a log file
' ----------------------------------
sub writetologfile(byval msg_text as string)
dim log_filename as string
log_filename = dte.solution.fullname
log_filename = path.changeextension(log_filename, ".log.txt")
try
dim sw as streamwriter = file.appendtext(log_filename)
sw.writeline(msg_text)
sw.close()
catch ex as exception
msgbox("log file write failed : " & ex.message)
end try
end sub
' ----------------------------------------------------------------
' write a text message to the build pane of the output tool window
' ----------------------------------------------------------------
sub writetooutputbuildpane(byval msg_text as string)
' create a tool window handle for the output window.
dim win as window = dte.windows.item(envdte.constants. _
qvswindowkindoutput)
' create handles to the output window and its build pane.
dim ow as outputwindow = win.object
dim owp as outputwindowpane
owp = ow.outputwindowpanes.item("build")
' add a line of text to the output pane.
owp.outputstring(msg_text & vbcrlf)
end sub
集成
注意! 如果你还没有一个macro project,那么先要创建一个.你需要打开一个macro project并显示在vs macros ide. (译者注:你可以通过快捷键alt + f8,或者点击view -> other windows -> macro explorer打开宏浏览窗口.双击其中一个宏,进行编辑.)
1. 每一个宏工程拥有一个名为environmentevents的页面,双击打开它.
2. 从类名称下拉列表中选择buildevents.
3. 从方法名下拉列表中选择onbuildprojconfigbegin.
4. 增加两个引用申明(import).
异常类的申明需要引用system名称空间. 文件的操作类申明需要引用system.io.
5. 在onbuildprojconfigbegin方法中添加.
6. 双击打开module1页面.
module1是ide使用的一个默认页面名称.如果你使用了不同的名称, 那么一定要修改onbuildprojconfigbegin中的对应名字空间.
添加两个辅助方法.
添加对 .system和.systemio.的引用申明.
运行
保存编辑结果,然后编译检查是否有错误.编译成功后,就可以直接使用了.使用很简单,这段代码会在每次编译时被执行.
新闻热点
疑难解答
图片精选