因为最近一家公司接触到这些东西,这里总结一下,有些东西没有深入,了解了一下。没有做具体的展开,只做了一个流程整理。有空做一个详细的展开吧。
1 搭建代码管理工具比如git或者svn之类,在构建机上登陆一个账号能够获取需要构建的资源,方便后边在脚本里边自动update
2 针对不同的项目实现相应的更新编译打包脚本,方便后边web服务器调用,个人用vs用的比较多,这里用vs举例。
第一步:编译
第一种:用devenv做参数启动进行编译,网上又具体的例子,这个只能编译解决方案,也就是sln后缀的解决方案文件,只要是vs支持的项目都可以编译,比如C#、C++、VB.NET等。具体的项目设置可以预先在解决方案和项目配置中设置好,
下边为具体的参数。这个devenv的路径可以写死或者直接写到环境变量中
devenv {/build|/clean|/rebuild|/deploy} SolnConfigName SolutionName[/project ProjName] [/projectconfig ProjConfigName]
第二种:可以用MSBuild来编译,这个是微软实现的开源编译工具,不过我个人看不大懂代码··这可以用来编译解决方案,也可以用来编译单独的项目:
在bat脚本中如数下边的代码可以导入MSBuild:
set "str=HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0_Config" for /f "tokens=2*" %%a in ('reg query "%str%" /v ShellFolder 2^>nul') do set "a=%%b" set a=%a%VC\vcvarsall.bat
示例:下边为调用示例
MSBuild ..\ExercisePrj.sln /t:Rebuild /P:WarningLevel=2;Configuration=Release;Platform=x86;DebugType=none;outdir=..\Release\;ApplicationIcon=..\Release\Resources\test.ico /flp1:errorsonly;logfile=build.err
上边两种方式都可以生成日志文件,指定生成的目录。
第二步:打包,把刚才编译生成的结果文件打包成文件就可以了,
根据不同的打包工具写脚本就可以了,打包就又很多选择了
1 可以用vs来做打包项目,不过这玩意不好使··以前有用过,用的不多,得益于vs的傻瓜式操作,基本看下提示就知道了,网上也教程的。这个生成的是一个msi安装包和一个exe引导程序。exe没什么用。不是太支持定制化需求
2 可以用advance,这个功能比较多,支持签名,注册,写注册表等等的操作,有可视化的界面来编辑他自己的项目文件,然后可以直接调用advance主程序做参数启动。可以生成msi或者exe程序
3 NSIS,网上有通用的脚本,改改就可以了,支持很多操作,包括写注册表、com注册等等的复杂操作,好像只能生成exe。下边是一个ebook的示例,注释很详细了,具体可以改,这个支持卸载覆盖安装注册和写注册表之类的操作。很好很强大
;增加一个包含链接内容的7z压缩包到可执行文件头部,使7-Zip打开看不到其他内容。 !packhdr temp.dat 'cmd /c Copy /B temp.dat /B +轻狂志.7z temp.dat' ; 安装程序初始定义常量 !define PRODUCT_NAME "eBook Workshop" !define PRODUCT_VERSION "v1.5简体中文增强版" !define PRODUCT_PUBLISHER "轻狂志" !define PRODUCT_WEB_SITE "http://www.flighty.cn" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" SetCompressor lzma ; ------ MUI 现代界面定义 (1.67 版本以上兼容) ------ !include "MUI.nsh" ; MUI 预定义常量 !define MUI_ABORTWARNING !define MUI_CUSTOMFUNCTION_GUIINIT onGUIInit !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_RIGHT !define MUI_HEADERIMAGE_BITMAP "top.bmp" !define MUI_PAGE_HEADER_TEXT "最终用户许可协议" !define MUI_PAGE_HEADER_SUBTEXT "您必须接受此协议才能继续安装!" !define MUI_LICENSEPAGE_TEXT_TOP "要阅读协议的其余部分请按 PgDn键 往下翻页。" !define MUI_LICENSEPAGE_TEXT_BOTTOM "如果你已经仔细阅读了许可协议,点击 下一步(N) > 继续安装。" !define MUI_LICENSEPAGE_BUTTON "下一步(&N) >" !define MUI_ICON "eBook Workshop.ico" !define MUI_UNICON "eBook Workshop.ico" !define MUI_WELCOMEFINISHPAGE_BITMAP "eBook Workshop.bmp" !define MUI_WELCOMEPAGE_TITLE "\r\n eBook Workshop v1.5安装向导" !define MUI_WELCOMEPAGE_TEXT "\r\n eBook Workshop(E书工场)是将 HTML 页面文件、图片、Flash等捆绑成 EXE 电子文档的制作软件。\r\n\r\n 相比原程序,本安装包主要进行了以下增强:\r\n 1、更换两套更为美观的E书工具栏图标,使用时更改安装目录下的Buttons文件夹即可;2、新增239个图标,分别位于Icon 2、Icon 3、Icon 4 这个3个文件夹内;3、集成了多个精美的E书主题界面,安装即可使用。4、安装过程中可以自动注册软件为正式版本,无任何功能限制。\r\n\r\n $_CLICK" !define MUI_FINISHPAGE_RUN_TEXT "运行 eBook Workshop" !define MUI_FINISHPAGE_SHOWREADME_TEXT "查看 安装说明" ; 欢迎页面 !insertmacro MUI_PAGE_WELCOME ; 许可协议页面 !insertmacro MUI_PAGE_LICENSE "许可协议.rtf" ; 组件选择页面 !insertmacro MUI_PAGE_COMPONENTS ; 安装目录选择页面 !insertmacro MUI_PAGE_DIRECTORY ; 安装过程页面 !insertmacro MUI_PAGE_INSTFILES ; 安装完成页面 !define MUI_FINISHPAGE_RUN "$INSTDIR\MAKER.exe" !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\说明.txt" !insertmacro MUI_PAGE_FINISH ; 安装卸载过程页面 !insertmacro MUI_UNPAGE_INSTFILES ; 安装界面包含的语言设置 !insertmacro MUI_LANGUAGE "SimpChinese" ; 安装预释放文件 !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ; ------ MUI 现代界面定义结束 ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "Setup.exe" InstallDir "$PROGRAMFILES\eBook Workshop" ;读取注册中的键值,如果没有,就按默认路径。 InstallDirRegKey HKCU "Software\eBook Workshop" "" ShowInstDetails show ShowUnInstDetails show BrandingText "轻狂志www.flighty.cn" Section "主程序" SEC01 SectionIn RO SetOutPath "$INSTDIR" SetOverwrite ifnewer File /r "eBook Workshop\主程序\*.*" CreateDirectory "$SMPROGRAMS\eBook Workshop" CreateShortCut "$SMPROGRAMS\eBook Workshop\eBook Workshop.lnk" "$INSTDIR\MAKER.exe" CreateShortCut "$DESKTOP\eBook Workshop.lnk" "$INSTDIR\MAKER.exe" SectionEnd Section "主题风格" SEC02 SetOutPath "$INSTDIR\Themes" File /r "eBook Workshop\Themes\*.*" SectionEnd Section "按钮图标" SEC03 SetOutPath "$INSTDIR" File /r "eBook Workshop\按钮图标\*.*" SectionEnd Section -AdditionalIcons WriteIniStr "$INSTDIR\轻狂志.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\eBook Workshop\轻狂志.lnk" "$INSTDIR\轻狂志.url" CreateShortCut "$SMPROGRAMS\eBook Workshop\卸载程序.lnk" "$INSTDIR\uninst.exe" SectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKCU "Software\eBook Workshop" "" $INSTDIR WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegStr HKCU "Software\Ada99\eBook Workshop" "AdaName" "QVNXb3Jk" WriteRegStr HKCU "Software\Ada99\eBook Workshop" "AdaKey" "NzE5RkJGNzEtMzUzQjQzNDQtQjcwQ0IxQTk=" WriteRegDWORD HKCU "Software\Ada99\eBook Workshop" "Language" 0x000003a8 SectionEnd #-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--# ; 区段组件描述 !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "将 HTML 页面文件、图片、Flash等捆绑成 EXE 电子文档的制作软件。" !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "多个精美的E书主题界面,安装即可使用。" !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "二百多个图标,分别位于Icon 2、Icon 3、Icon 4 这个3个文件夹内。" !insertmacro MUI_FUNCTION_DESCRIPTION_END /****************************** * 以下是安装程序的卸载部分 * ******************************/ Section Uninstall Delete "$INSTDIR\*.*" Delete "$SMPROGRAMS\eBook Workshop\*.lnk" Delete "$DESKTOP\eBook Workshop.lnk" RMDir "$SMPROGRAMS\eBook Workshop" RMDir /r "$INSTDIR\Themes\银色苹果" RMDir /r "$INSTDIR\Themes\新奇前卫" RMDir /r "$INSTDIR\Themes\前卫幻想深绿色" RMDir /r "$INSTDIR\Themes\前卫幻想绿色" RMDir /r "$INSTDIR\Themes\前卫幻想蓝色" RMDir /r "$INSTDIR\Themes\灵界军团" RMDir /r "$INSTDIR\Themes\蓝色妖姬v2005" RMDir /r "$INSTDIR\Themes\蓝色妖姬" RMDir /r "$INSTDIR\Themes\蓝色心情" RMDir /r "$INSTDIR\Themes\金属时代" RMDir /r "$INSTDIR\Themes\简约之美" RMDir /r "$INSTDIR\Themes\黄色之旅" RMDir /r "$INSTDIR\Themes\黄昏幻想" RMDir /r "$INSTDIR\Themes\海洋之心v2005" RMDir /r "$INSTDIR\Themes\海洋之心" RMDir /r "$INSTDIR\Themes\古色古香" RMDir /r "$INSTDIR\Themes\半成卷轴" RMDir /r "$INSTDIR\Themes\Wood" RMDir /r "$INSTDIR\Themes\WinXP" RMDir /r "$INSTDIR\Themes\Water" RMDir /r "$INSTDIR\Themes\ThemeXP" RMDir /r "$INSTDIR\Themes\POPO2004_3" RMDir /r "$INSTDIR\Themes\POPO2004_2" RMDir /r "$INSTDIR\Themes\POPO2004" RMDir /r "$INSTDIR\Themes\Ocean" RMDir /r "$INSTDIR\Themes\Notepad" RMDir /r "$INSTDIR\Themes\New-Royale" RMDir /r "$INSTDIR\Themes\New-PantherS" RMDir /r "$INSTDIR\Themes\New-Mento" RMDir /r "$INSTDIR\Themes\New-Element" RMDir /r "$INSTDIR\Themes\New-Dogmax" RMDir /r "$INSTDIR\Themes\Mustang" RMDir /r "$INSTDIR\Themes\Metal" RMDir /r "$INSTDIR\Themes\MacOSX" RMDir /r "$INSTDIR\Themes\Love" RMDir /r "$INSTDIR\Themes\G-star" RMDir /r "$INSTDIR\Themes\GreenWinXP" RMDir /r "$INSTDIR\Themes\ExoBUD MP" RMDir /r "$INSTDIR\Themes\BlueWinXP" RMDir /r "$INSTDIR\Themes\BlueLove" RMDir /r "$INSTDIR\Themes\Apple" RMDir /r "$INSTDIR\LANGUAGE" RMDir /r "$INSTDIR\Buttons" RMDir /r "$INSTDIR\Buttons 2" RMDir /r "$INSTDIR\Icon" RMDir /r "$INSTDIR\Icon 4" RMDir /r "$INSTDIR\Icon 3" RMDir /r "$INSTDIR\Icon 2" RMDir "$INSTDIR\Themes" RMDir "$INSTDIR" ;卸载注册表中的软件注册键值 DeleteRegKey /ifempty HKCU "Software\Ada99\eBook Workshop" ;卸载注册表中安装路径的键值 DeleteRegKey /ifempty HKCU "Software\eBook Workshop" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" SetAutoClose true SectionEnd #-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--# Function onGUIInit BrandingURL::Set /NOUNLOAD "200" "0" "0" "http://www.flighty.cn" FunctionEnd Function .onGUIEnd BrandingURL::Unload FunctionEnd Function un.onInit MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您确实要完全移除 $(^Name) ,及其所有的组件?" IDYES +2 Abort FunctionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除。" FunctionEnd
这里有几个问题:
1》 定制需求:因为公司的产品会有标准本以及定制UI的定制需求,比如替换一些资源文件之类的,这些可以通过bat脚本来复制后替换,然后打包
2》版本控制: 以上边的vs项目举例子,vs生成的dll和exe文件版本号可以通过AssemblyInfo来设置的,设置一些公司信息和版本号,也支持签名。这个如果用手动改的话就比较麻烦了没法做到自动化,因为这个文件的格式是已知的,所以可以写一个小程序每次动态的修改这个文件来控制编译,这样编译出来的文件就带相应的信息了。可以把定制的公司信息也通过svn来管理然后拷贝过来直接编译。至于版本号可以获取svn或者git的版本号来作为版本号。至于签名文件我没试过在vs中使用,可以尝试
上边是编译的时候修改,这样有点麻烦,或者局限,还有一种是生成以后修改生成的exe程序,这样听起来有点想黑客一样,因为理论上编译以后的文件应该不能修改,有一个工具可以修改windows下的可执行文件的相关资源信息,百度下resource hacker,可以修改exe的相关信息,比如公司或者版本号。签名可以用微软官方提供的SignTool.exe程序。需要准备好证书文件。
打包以后的文件可以拷贝的一个指定的目录。方便后边下载使用。
3 编译和打包脚本弄好,需要一个简单的web服务端来调用,同时控制脚本的执行,因为本人没有web开发的经验,这里用asp.net mvc写一个简单的页面,简单的实现下。在一个指定目录下获取所有bat脚本,然后显示到web页就行了。
这里用了一个静态变量来缓存当前执行的任务,实际应该用一个简单的数据库来缓存,这样可以在web页查询执行的状态。这里可以随便用什么实现一个简单的web服务端就行了比如python或者java都行。
const string root = @"E:\bats\"; static List<string> TaskList = new List<string>(); private static object lockobj = new object(); public IActionResult BatList() { ViewData["Message"] = "Bat List page."; var dir = new DirectoryInfo(root); var bats = dir.EnumerateFiles("*.bat").Select(f=>f.Name).AsEnumerable() ; ViewData["Bats"] = bats; return View(); } [Produces("application/text")] [HttpPost] public IActionResult DoBat(string file) { var msg = $"{DateTime.Now.ToString()}:{file}"; var fullpath = root + file; if(TaskList.Contains(fullpath)) return new JsonResult($"{DateTime.Now.ToString()}:{file} allready run"); ProcessStartInfo startInfo = new ProcessStartInfo(fullpath); startInfo.WindowStyle = ProcessWindowStyle.Normal; startInfo.CreateNoWindow = true; startInfo.UseShellExecute = true; var pro= Process.Start(startInfo); lock(lockobj) { TaskList.Add(fullpath); } pro.Exited += Pro_Exited; Log(msg); return new JsonResult(msg); } private void Pro_Exited(object sender, EventArgs e) { var pro = sender as Process; var task = pro.StartInfo.FileName; Remove(task); } void Log(string msg) { using (StreamWriter sw = new StreamWriter(root + "log.txt",true)) { sw.WriteLine(msg); } } void Remove(string task) { lock (lockobj) { if (TaskList.Contains(task)) TaskList.Remove(task); } }
cshtml文件主要代码如下:
@{ var list = ViewData["Bats"] as IEnumerable<string>; foreach (var f in list) { <a href="#" onclick="getInfo('@(f)')">@fa> <br /> } }
链接的执行方法写的比较别扭,勉强能用吧:
function getInfo(file) { $.ajax({ url: '/home/DoBat?file='+file, type: 'POST', data: JSON.stringify({file:file}), contentType: 'application/json;charset=UTF-8', datatype:"json", success: function (result) { alert(result); } }) }
4 web服务端弄好了,可以在局域网内访问,进行打包服务,下边需要一个下载安装包的途径,这里推荐两个方式:
第一个搭一个ftp服务器,windows下可以直接用iis搭一个ftp服务器,很方便,吧生成安装包的目录挂上ftp就行了。
或者http的文件服务器。比如hfs,很简单,可以直接指定目录,这玩意不稳定,死机了重启就好了。
到这自动构建的环境就完成。
除此之外:
还需要的环境,下边的没什么研究,
1 审批平台,svn或者git的审批平台,用来做代码review的。有一个开源的工具,这个暂时没研究
2 测试平台,就用禅道就可以了,凑合使了,
3 wiki,文档之类的资源共享平台。