之前有一个winfrom项目,想要通过获取SVN版本号作为程序的内部编译版本号。网上也有各种方法,但没有一篇行得通的方法。于是我经过一系列研究,得出了一些经验,特总结成一篇博客。

方法一:通过SVN命令获取版本号

类似地,我在项目中添加了一个名为"Version_inf.bat"的用于生成版本号的批处理文件,把他放在启动项目的目录中。批处理文件中写下如下脚本:

    svn info>bin\Debug\SVN_Version.dll
findstr “Revision” bin\Debug\SVN_Version.dll

这段脚本的意思是通过“svn info”命令获取“Revision”版本信息到Debug的输出目录的“SVN_Version.dll”文件中。(前提是电脑上必须安装了svn软件才能正常使用此命令。)

在程序的Program主入口中,写上类似的代码:

     string str_PathResult = null;
Microsoft.Win32.RegistryKey regKey = null;//表示 Windows 注册表中的项级节点(注册表对象?)
Microsoft.Win32.RegistryKey regSubKey = null;
try
{
regKey = Microsoft.Win32.Registry.LocalMachine;//读取HKEY_LOCAL_MACHINE项 if (regKey != null)
{
string keyPath = @"SOFTWARE\TortoiseSVN";
regSubKey = regKey.OpenSubKey(keyPath, false);
}
//得到SVN安装路径
if (regSubKey != null)
{
if (regSubKey.GetValue("Directory") != null)
{
str_PathResult = regSubKey.GetValue("Directory").ToString();
}
} //如果存在SVN安装信息,则通过调用批处理获取版本号
if (str_PathResult != null)
{
string path = System.Environment.CurrentDirectory;
////删除已经存在的版本信息,避免出现串号
//if (File.Exists(path + "\\SVN_Version.dll"))
//{
// File.Delete(path + "\\SVN_Version.dll");
//} int pathNum = path.LastIndexOf("\\") - ;
ProcessStartInfo psi = new ProcessStartInfo(); string pathStr = path.Substring(, pathNum) + "Version_inf.bat";
//string newPathStr = (pathStr.Substring(0, pathStr.LastIndexOf("."))) + ".bat"; psi.FileName = pathStr;
//psi.FileName = path.Substring(0, pathNum) + "Version_inf.bat";
psi.UseShellExecute = false;
psi.WorkingDirectory = path.Substring(, pathNum).Substring(, path.Substring(, pathNum).Length - );
psi.CreateNoWindow = true;
Process.Start(psi);
}
}
catch (Exception ex)
{
//MessageBox.Show("检测SVN信息出错," + ex.ToString(), "提示信息");
//LogUtil.WriteException(ex, "Program.Main()");
}
finally
{
if (regKey != null)
{
regKey.Close();
regKey = null;
} if (regSubKey != null)
{
regSubKey.Close();
regSubKey = null;
}
}

这样每次程序编译的时候就会生成一个新的“SVN_Version.dll”文件,里面记录了最后一次更新的记录版本号。

然后在主窗口读取“SVN_Version.dll”文件中的版本信息显示到程序的主界面上,代码如下:

     AssemblyName name = Assembly.GetExecutingAssembly().GetName();
String version = name.Version.ToString().Substring(, name.Version.ToString().LastIndexOf("."));
//SVN版本号文件保存路径
String svnVersionPath = System.AppDomain.CurrentDomain.BaseDirectory + "SVN_Version.dll";
if (File.Exists(svnVersionPath))
{
//StreamReader svnSteamReader = new StreamReader(svnVersionPath);
string[] lines = File.ReadAllLines(svnVersionPath);
if (lines.Length > )
{
for (int i = ; i < lines.Length; i++)
{
if (lines[i].Contains("Revision"))
{
String[] temps = lines[i].Split(':');
if (temps.Length > )
{
version += String.Format(".{0}", temps[].Trim());
break;
}
}
}
tssVersion.Text += version;
}
else
{
tssVersion.Text += "获取出错";
}
}
else
{
tssVersion.Text += "未知的版本";
}

这样就完成了SVN版本号的获取和内部编译号的显示了。如下图:

但是这种的方法的问题是:

1)svn命令在程序没有变化或者没有获取最新版本时会无法生成版本号;

2)只是在主界面显示了版本号,但是并没有真正改变项目生成文件的版本号;

3)如果电脑中没有安装svn程序,则极有可能会出现错误;

所以我又研究了方法二。

方法二:通过项目预处理事件获取SVN版本号

先在项目的Properties目录下新建一个“AssemblyInfo.template.cs”的模板类文件,并把“AssemblyInfo.cs”文件从SVN版本号中忽略。在模板文件中写下类似的代码:

 using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; // 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("程序名")]
[assembly: AssemblyDescription("更新时间:$WCDATE$")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("程序名")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("18501865-f051-43be-ab03-59a2d9e76fcf")] // 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 内部版本号
// 修订号
//
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.1.$WCREV$")]
[assembly: AssemblyFileVersion("1.1.1.$WCREV$")]

然后在项目属性的生成事件中编写如下预先生成事件执行的命令:

 $(SolutionDir)Lib\SubWCRev.exe $(SolutionDir) $(ProjectDir)Properties\AssemblyInfo.template.cs $(ProjectDir)Properties\AssemblyInfo.cs -f

这段话的意思就是找到SVN的SubWCRev.exe文件,获取到版本信息后通过模板将数据写入到“AssemblyInfo.cs”文件中。

这样每次生成之后版本号就写入到了项目输出的文件中。将每个项目都按照如上方法添加模板和预生成事件,那么程序文件就会都带有版本信息。

实际效果如下图所示:

程序在显示的时候,可以通过封装一个公共属性让其他人可以调用到版本号信息:

   /// <summary>
/// 版本号
/// </summary>
public static string AppVersion
{
set { AppDomain.CurrentDomain.SetData("AppVersion", value); }
get { return AppDomain.CurrentDomain.GetData("AppVersion") == null ? "" : AppDomain.CurrentDomain.GetData("AppVersion").ToString(); }
}

这样就大功告成啦!!!

当然如果想获取项目生成的文件或者想获取某个指定文件的版本号属性,可以使用如下方法:

 /// <summary>
/// 获取文件的版本号
/// </summary>
/// <param name="filePath">文件的完整路径</param>
/// <returns>文件的版本号</returns>
public static string GetFileVersion(string filePath)
{
string FileVersions = ""; try
{
System.Diagnostics.FileVersionInfo file1 = System.Diagnostics.FileVersionInfo.GetVersionInfo(filePath);
FileVersions = file1.FileVersion;
if (FileVersions != "")
{
string[] strVer = FileVersions.Split('.');
if (strVer.Length == )
{
FileVersions = strVer[] + ".00.0000";
} }
}
catch (Exception ex)
{
FileVersions = "";
}
return FileVersions;
}

特别说明:本文章为本人Healer007 原创! 署名:小萝卜  转载请注明出处,谢谢!

C#:通过Visual Studio项目预生成命令获取SVN版本号的更多相关文章

  1. Visual Studio项目的生成事件代码

    我们打开vs的项目属性可以看到有生成事件,如下图: 可以看到有两块空白区域,这个空白区域可以让我们写代码或脚本来处理编译生成前后的时候,处理一些事情,今天就简单的来说说这两块. 生成前事件命令行 我想 ...

  2. 怎么将visual studio项目打包生成dll文件

    1.打开电脑再打开visual studio软件,在软件里面新建一个项目,文件---->新建---->项目,打开新建项目窗口. 2.选择C#类工程,并为项目命名. 3.将类库文件class ...

  3. 因GIT默认忽略.dll文件导致的Visual Studio项目通过Bamboo编译失败

    背景 由GIT管理的Visual Studio项目,使用Stash管理远端代码库,通过与Stash集成的Bamboo生成项目并发布 现象 Visual Studio项目本地生成成功,用SourceTr ...

  4. 在Visual Studio中新增生成项目

    在Visual Studio中新增生成项目 选择适配器类型 选择WCF-SQL适配器 创建连接选项 选择相应的存储过程 生成相应的消息架构

  5. 【译】Visual Studio 15 预览版更新说明

    序:恰逢Build2016大会召开,微软发布了VS2015的update2更新包和VS2016预览版.本人正在提升英文水平中,于是在这里对VS2016预览版的官方文档进行了部分翻译.因为VS有些功能使 ...

  6. Visual Studio 2019预览,净生产力

    本文章为机器翻译. https://blogs.msdn.microsoft.com/dotnet/2018/12/13/visual-studio-2019-net-productivity/ 该文 ...

  7. 关于在Visual Studio 2019预览版中的用户体验和界面的变化

    原文地址:https://blogs.msdn.microsoft.com/visualstudio/2018/11/12/a-preview-of-ux-and-ui-changes-in-visu ...

  8. Visual Studio 2022 预览版3 最新功能解说

    我们很高兴地宣布Visual Studio 2022 的第三个预览版问世啦!预览版3 提供了更多关于个人和团队生产力.现代开发和持续创新等主题的新功能.在本文中,我们将重点介绍Visual Studi ...

  9. 创建用于自定义SharePoint解决方案部署的Visual Studio项目

    转:http://soft.zdnet.com.cn/software_zone/2007/0903/488083.shtml 在基于SharePoint的开发中,我们通常会在WSS的TEMPLATE ...

随机推荐

  1. NGUI 使用UITable(或UIGrid)注意事项

    在ScrollView显示区域中,若Item数量不足以超出显示区域,有可能不是贴着ScrollView最边缘位置显示!这个时候可以按如下方法调整: 因为实际情况中,往ScrollView中添加Item ...

  2. 最长子串 FZU2118

    http://acm.fzu.edu.cn/problem.php?pid=2128 分析:利用strstr()函数将每个字串在原串中的首尾位置存储一下,再将首尾从小到大排一下序.(写着写着就感觉和看 ...

  3. hdu4738 Caocao's Bridges

    http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:曹操赤壁之战大败,于是卷土重来.为了避免水上作战,他在长江上建立了一些岛屿,这样他的士兵就可以在 ...

  4. 数据库管理员<三>

    数据库管理员  介绍 每个 oracle 数据库应该至少有一个数据库管理员(dba),对于一个小的数据库,一个 dba 就够了,但是对于一个大的数据库 可能需要多个 dba 分担不同的管理职责.那么 ...

  5. Nodejs编码转化问题

    目前Node.js仅支持hex.utf8.ascii.binary.base64.ucs2几种编码的转换.对于GBK,GB2312等编码,Nodejs自带的toString()方法不支持,因此中文转化 ...

  6. MongoDB数据库简介及安装

    一.MongoDB数据库简介 简介 MongoDB是一个高性能,开源,无模式的,基于分布式文件存储的文档型数据库,由C++语言编写,其名称来源取自"humongous",是一种开源 ...

  7. Intellij idea 设置svn 父目录文件显示状态颜色

    file-->setting-->version control

  8. ios php RSA 非对称加密解密 der 和pem生成

    ios 使用public_key.der加密 php 使用 private_key.pem解密 openssl req -x509 -out public_key.der -outform der - ...

  9. php中英文截取无乱码 包括全角下的字符

    符合UTF-8下,如果GBK下  改为  $content .= $str[$sing].$str[$sing+1];        $sing += 3; 改为 $sing += 2; /**    ...

  10. Oracle创建表(包含、主键自增)

    注意:Oracle导出建表语句不会导出触发器及自增索引 第一步:创建一张表 create table member( memberId number primary key, --主键.自增长 mem ...