Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I think I have an answer for you. This will be a bit involved, but it gets you away from having to do any batch files. You can rely on MSBuild and Custom Tasks to do this for you. I've used the extension pack for MSBuild (Available at <a href="http://msbuildextensionpack.codeplex.com/" rel="noreferrer">CodePlex</a>) - but the second task you need is something you could just as easily write yourself. </p> <p>With this solution, you can right click on the DLL and see in the file properties which Mercurial Version the DLL (or EXE) came from.</p> <p>Here are the steps:</p> <ol> <li>Get the <a href="http://msbuildextensionpack.codeplex.com/" rel="noreferrer">MBBuildExtension Pack</a> <strong>OR</strong> Write Custom Task to overwrite AssemblyInfo.cs </li> <li>Create a Custom Build Task in its own project to get the Mercurial Id(code below). </li> <li>Edit project files that need the Mercurial Id to use Custom Task (code below).</li> </ol> <p><strong>Custom Task to Get mercurial id:</strong> (This would need to be tested well and perhaps better generalized...)</p> <pre><code>using System; using System.Diagnostics; using Microsoft.Build.Utilities; using Microsoft.Build.Framework; namespace BuildTasks { public class GetMercurialVersionNumber : Task { public override bool Execute() { bool bSuccess = true; try { GetMercurialVersion(); Log.LogMessage(MessageImportance.High, "Build's Mercurial Id is {0}", MercurialId); } catch (Exception ex) { Log.LogMessage(MessageImportance.High, "Could not retrieve or convert Mercurial Id. {0}\n{1}", ex.Message, ex.StackTrace); Log.LogErrorFromException(ex); bSuccess = false; } return bSuccess; } [Output] public string MercurialId { get; set; } [Required] public string DirectoryPath { get; set; } private void GetMercurialVersion() { Process p = new Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.StartInfo.WorkingDirectory = DirectoryPath; p.StartInfo.FileName = "hg"; p.StartInfo.Arguments = "id"; p.Start(); string output = p.StandardOutput.ReadToEnd().Trim(); Log.LogMessage(MessageImportance.Normal, "Standard Output: " + output); string error = p.StandardError.ReadToEnd().Trim(); Log.LogMessage(MessageImportance.Normal, "Standard Error: " + error); p.WaitForExit(); Log.LogMessage(MessageImportance.Normal, "Retrieving Mercurial Version Number"); Log.LogMessage(MessageImportance.Normal, output); Log.LogMessage(MessageImportance.Normal, "DirectoryPath is {0}", DirectoryPath); MercurialId = output; } } </code></pre> <p><strong>And the modified Project File:</strong> (The comments may help)</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; &lt;!--this is the import tag for the MSBuild Extension pack. See their documentation for installation instructions.--&gt; &lt;Import Project="C:\Program Files (x86)\MSBuild\ExtensionPack\MSBuild.ExtensionPack.tasks" /&gt; &lt;!--Below is the required UsingTask tag that brings in our custom task.--&gt; &lt;UsingTask TaskName="BuildTasks.GetMercurialVersionNumber" AssemblyFile="C:\Users\mpld81\Documents\Visual Studio 2008\Projects\LambaCrashCourseProject\BuildTasks\bin\Debug\BuildTasks.dll" /&gt; &lt;PropertyGroup&gt; &lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt; &lt;Platform Condition=" '$(Platform)' == '' "&gt;AnyCPU&lt;/Platform&gt; &lt;ProductVersion&gt;9.0.30729&lt;/ProductVersion&gt; &lt;SchemaVersion&gt;2.0&lt;/SchemaVersion&gt; &lt;ProjectGuid&gt;{D4BA6C24-EA27-474A-8444-4869D33C22A9}&lt;/ProjectGuid&gt; &lt;OutputType&gt;Library&lt;/OutputType&gt; &lt;AppDesignerFolder&gt;Properties&lt;/AppDesignerFolder&gt; &lt;RootNamespace&gt;LibraryUnderHg&lt;/RootNamespace&gt; &lt;AssemblyName&gt;LibraryUnderHg&lt;/AssemblyName&gt; &lt;TargetFrameworkVersion&gt;v3.5&lt;/TargetFrameworkVersion&gt; &lt;FileAlignment&gt;512&lt;/FileAlignment&gt; &lt;/PropertyGroup&gt; &lt;PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "&gt; &lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt; &lt;DebugType&gt;full&lt;/DebugType&gt; &lt;Optimize&gt;false&lt;/Optimize&gt; &lt;OutputPath&gt;bin\Debug\&lt;/OutputPath&gt; &lt;DefineConstants&gt;DEBUG;TRACE&lt;/DefineConstants&gt; &lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; &lt;WarningLevel&gt;4&lt;/WarningLevel&gt; &lt;/PropertyGroup&gt; &lt;PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "&gt; &lt;DebugType&gt;pdbonly&lt;/DebugType&gt; &lt;Optimize&gt;true&lt;/Optimize&gt; &lt;OutputPath&gt;bin\Release\&lt;/OutputPath&gt; &lt;DefineConstants&gt;TRACE&lt;/DefineConstants&gt; &lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; &lt;WarningLevel&gt;4&lt;/WarningLevel&gt; &lt;/PropertyGroup&gt; &lt;ItemGroup&gt; &lt;Reference Include="System" /&gt; &lt;Reference Include="System.Core"&gt; &lt;RequiredTargetFramework&gt;3.5&lt;/RequiredTargetFramework&gt; &lt;/Reference&gt; &lt;Reference Include="System.Xml.Linq"&gt; &lt;RequiredTargetFramework&gt;3.5&lt;/RequiredTargetFramework&gt; &lt;/Reference&gt; &lt;Reference Include="System.Data.DataSetExtensions"&gt; &lt;RequiredTargetFramework&gt;3.5&lt;/RequiredTargetFramework&gt; &lt;/Reference&gt; &lt;Reference Include="System.Data" /&gt; &lt;Reference Include="System.Xml" /&gt; &lt;/ItemGroup&gt; &lt;ItemGroup&gt; &lt;Compile Include="Class1.cs" /&gt; &lt;Compile Include="Properties\AssemblyInfo.cs" /&gt; &lt;/ItemGroup&gt; &lt;Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /&gt; &lt;Target Name="Build" DependsOnTargets="BeforeBuild"&gt; &lt;!--This Item group is a list of configuration files to affect with the change. In this case, just this project's.--&gt; &lt;ItemGroup&gt; &lt;AssemblyInfoFiles Include="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs" /&gt; &lt;/ItemGroup&gt; &lt;!--Need the extension pack to do this. I've put the Mercurial Id in the Product Name Attribute on the Assembly.--&gt; &lt;MSBuild.ExtensionPack.Framework.AssemblyInfo AssemblyInfoFiles="@(AssemblyInfoFiles)" AssemblyProduct="Hg: $(MercurialId)" /&gt; &lt;!--This is here as an example of messaging you can use to debug while you are setting yours up.--&gt; &lt;Message Text="In Default Target, File Path is: @(AssemblyInfoFiles)" Importance="normal" /&gt; &lt;/Target&gt; &lt;Target Name="BeforeBuild"&gt; &lt;!--This is the custom build task. The Required Property in the task is set using the property name (DirectoryPath)--&gt; &lt;BuildTasks.GetMercurialVersionNumber DirectoryPath="$(MSBuildProjectDirectory)"&gt; &lt;!--This captures the output by reading the task's MercurialId Property and assigning it to a local MSBuild Property called MercurialId - this is reference in the Build Target above.--&gt; &lt;Output TaskParameter="MercurialId" PropertyName="MercurialId" /&gt; &lt;/BuildTasks.GetMercurialVersionNumber&gt; &lt;/Target&gt; &lt;!--&lt;Target Name="AfterBuild"&gt; &lt;/Target&gt;--&gt; &lt;/Project&gt; </code></pre> <p>Last Note: The build tasks project only needs to be built once. Don't try to build it every time you do the rest of your solution. If you do, you will find that VS2008 has the dll locked. Haven't figured that one out yet, but I think the better thing to do is build the dll as you want it, then distribute ONLY the dll with your code, ensuring that the dll's location is fixed relative to every project you need to use it in. That way, no one has to install anything. </p> <p>Good luck, and I hope this helps!</p> <p>Audie</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload