Win*_*ith 53 .net c# deployment visual-studio-2005 visual-studio
假设我想创建一个随每个版本一起提供的静态文本文件.我希望使用版本的版本号(如中所述AssemblyInfo.cs
)更新文件,但我不想手动执行此操作.
我希望我可以使用post-build事件并将版本号提供给批处理文件,如下所示:
call foo.bat $(AssemblyVersion)
Run Code Online (Sandbox Code Playgroud)
但是我找不到任何合适的变量或宏来使用.
有没有办法实现这一点,我错过了?
Bre*_*ias 90
如果(1)您不想下载或创建检索程序集版本的自定义可执行文件,并且(2)您不介意编辑Visual Studio项目文件,那么有一个简单的解决方案允许您使用宏看起来像这样:
@(目标 - > '%(版)')
@(VersionNumber)
Run Code Online (Sandbox Code Playgroud)
要完成此任务,请卸载您的项目.如果某个项目定义了一个<PostBuildEvent>属性,请将其从项目中删除并暂时保存在其他位置(记事本?).然后在项目的最后,就在结束标记之前,放置:
<Target Name="PostBuildMacros">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="Targets" />
</GetAssemblyIdentity>
<ItemGroup>
<VersionNumber Include="@(Targets->'%(Version)')"/>
</ItemGroup>
</Target>
<PropertyGroup>
<PostBuildEventDependsOn>
$(PostBuildEventDependsOn);
PostBuildMacros;
</PostBuildEventDependsOn>
<PostBuildEvent>echo HELLO, THE ASSEMBLY VERSION IS: @(VersionNumber)</PostBuildEvent>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
此代码段中已包含一个示例<PostBuildEvent>.不用担心,您可以在重新加载项目后将其重置为真正的构建后事件.
现在按照承诺,使用此宏可以为您的post build事件提供程序集版本:
@(VersionNumber)
Run Code Online (Sandbox Code Playgroud)
完成!
小智 16
如果您更喜欢编写脚本,这些方法可能对您有用:
如果您使用的是构建后事件,则可以使用filever.exe工具从已构建的程序集中获取它:
for /F "tokens=4" %%F in ('filever.exe /B /A /D bin\debug\myapp.exe') do (
set VERSION=%%F
)
echo The version is %VERSION%
Run Code Online (Sandbox Code Playgroud)
从这里获取filever.exe:http://support.microsoft.com/kb/913111
如果您正在使用预构建事件,则可以将其从AssemblyInfo.cs文件中取出,如下所示:
set ASMINFO=Properties\AssemblyInfo.cs
FINDSTR /C:"[assembly: AssemblyVersion(" %ASMINFO% | sed.exe "s/\[assembly: AssemblyVersion(\"/SET CURRENT_VERSION=/g;s/\")\]//g;s/\.\*//g" >SetCurrVer.cmd
CALL SetCurrVer.cmd
DEL SetCurrVer.cmd
echo Current version is %CURRENT_VERSION%
Run Code Online (Sandbox Code Playgroud)
这使用unix命令行工具sed,您可以从许多地方下载,例如:http://unxutils.sourceforge.net/ - iirc,一个正常工作.
Win*_*ith 12
作为一种解决方法,我编写了一个托管控制台应用程序,它将目标作为参数,并返回版本号.
我仍然有兴趣听一个更简单的解决方案 - 但我发布这个以防其他人发现它有用.
using System;
using System.IO;
using System.Diagnostics;
using System.Reflection;
namespace Version
{
class GetVersion
{
static void Main(string[] args)
{
if (args.Length == 0 || args.Length > 1) { ShowUsage(); return; }
string target = args[0];
string path = Path.IsPathRooted(target)
? target
: Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + Path.DirectorySeparatorChar + target;
Console.Write( Assembly.LoadFile(path).GetName().Version.ToString(2) );
}
static void ShowUsage()
{
Console.WriteLine("Usage: version.exe <target>");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个答案是布伦特阿里亚斯答案的一个小修改.他的PostBuildMacro对我来说效果很好,直到Nuget.exe的版本更新.
在最近的版本中,Nuget修剪了包版本号的非重要部分,以获得类似"1.2.3"的语义版本.例如,程序集版本"1.2.3.0"由Nuget.exe"1.2.3"格式化.并且"1.2.3.1"按预期格式化为"1.2.3.1".
由于我需要推断Nuget.exe生成的确切包文件名,我现在使用这个自适应宏(在VS2015中测试):
<Target Name="PostBuildMacros">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="Targets" />
</GetAssemblyIdentity>
<ItemGroup>
<VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace("%(Targets.Version)", "^(.+?)(\.0+)$", "$1"))" />
</ItemGroup>
</Target>
<PropertyGroup>
<PostBuildEventDependsOn>
$(PostBuildEventDependsOn);
PostBuildMacros;
</PostBuildEventDependsOn>
<PostBuildEvent>echo HELLO, THE ASSEMBLY VERSION IS: @(VersionNumber)</PostBuildEvent>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
更新2017-05-24:我以这种方式纠正了正则表达式:"1.2.0.0"将被翻译为"1.2.0"而不是之前编码的"1.2".
要回答Ehryk Apr的评论,您可以调整正则表达式以仅保留版本号的某些部分.作为保留"Major.Minor"的示例,替换:
<VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace("%(Targets.Version)", "^(.+?)(\.0+)$", "$1"))" />
Run Code Online (Sandbox Code Playgroud)
通过
<VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace("%(Targets.Version)", "^([^\.]+)\.([^\.]+)(.*)$", "$1.$2"))" />
Run Code Online (Sandbox Code Playgroud)
我不知道为什么,但 Brent Arias 宏对我不起作用(@(VersionNumber)
总是空的):( .Net6 VS2022。我最终得到了稍微修改过的版本:
<Target Name="GetVersion" AfterTargets="PostBuildEvent">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
</GetAssemblyIdentity>
<PropertyGroup>
<VersionInfo>%(AssemblyInfo.Version)</VersionInfo>
</PropertyGroup>
<!--And use it after like any other variable:-->
<Message Text="VersionInfo = $(VersionInfo)" Importance="high" />
</Target>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
29411 次 |
最近记录: |