Wednesday, June 30, 2010

Automatically increment the assemblys version

Automatically increment the assemblys version

First of all let me say that credit goes to Christian Binder whose blog article was the reason why I got things working in the first place. Thank Chris! Since his howto is in german, I will translate most of it here. For reference, please visit his blog!

So this is what this article is about: Imagine you were doing nightly builds of your software. Sure enough you wouldn't want to touch every AssemblyInfo.cs or .vb every day only for manually incrementing the version number. The Assembly version number basically looks like this:

MajorVersion.MinorVersion.BuildNumber.Revision.

What you want to achieve is that you can see the Assembly version in the file properties in explorer so that you know which release build it refers to.

To know which release build the Assembly refers to, you need the buildnumber Team Build assigned to the release. The naming convention looks like this: Buildname + Date + Revision. So if you built your FooBar application today already the third time, its buildnumber would be FooBar_20090128.3. Easy, huh?

While FooBar's sources are labled with that buildnumber, the Assembly properties are not altered.

The settings you would want Team Build to alter are these:

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Before I go into details about what Chris did to get things working, let me add the following:

My project consists of several solutions. I have libraries for example that are shared amongst several projects. This is why I only wanted to have build definitions that contained the main project and the referenced libraries. However, for automatically checking out and back in the AssemblyInfo files while editing them at build time, Chris uses the /recursive argument to recursively go through all subdirectories and touch all AssemblyInfo files. When having more than one workspace in your build definition that explicitly copy only specific projects to Team Builds' local workspace, that does not work.

However, he also shows how to create a list of all AssemblyInfo files within the folder structure. And I changed his TFS tasks so that instead of the recursive argument the list generated earlier is used. That works like a charm!

And this is how you extend the build process to let Team Build automatically set the version information:

 1. Download and install AssemblyInfoTask

You need to get this custom build task. Chris references the original source at gotdotnet.com which does not exist anymore. Either search for the text AssemblyInfoTaskvers with google or try this link. It should redirect you to the download area on MSDN where you can get the lates setup release.

2. Import the task into your build project

Open Source Control in Visual Studio and make sure you have a local copy of the build project in your workspace. Then check out the TFSBuild.proj file (Unchanged, keep any existing lock) and open it. Add the following line right after the import of Microsoft.TeamFoundation.Build.targets: 

<Import Project="$(MSBuildExtensionsPath)¥Microsoft¥AssemblyInfoTask¥Microsoft.VersionNumber.Targets"/> 

3. Use a custom task for retrieving the revision number

Each buildnumber contains a revision: FooBar_20090128.3 What we want to do is using this revision number also as revision in our Assembly version. So we need to implement a custom build task that is able to extract the revision number from the buildnumber so that we can assign it to the Assemblys' revision number. At the end of this article, I will post the sources you will need.

Right after the import statement from above, register this custom build task by adding the following line: 

<UsingTask TaskName="ExtractRevision.ExtractRevisionTask" AssemblyFile="ExtractRevision.dll"/> 

 4. Add a property group for setting the assembly information

To configure all assembly properties and format the number formats respectively, add the following lines to your project file:

  <PropertyGroup>

    <!– Assembly version properties. Add others here –>

    <AssemblyMajorVersion>4</AssemblyMajorVersion>

    <AssemblyMinorVersion>0</AssemblyMinorVersion>

    <AssemblyBuildNumber>0</AssemblyBuildNumber>

    <AssemblyRevision>0</AssemblyRevision>

 

    <AssemblyFileMajorVersion>4</AssemblyFileMajorVersion>

    <AssemblyFileMinorVersion>0</AssemblyFileMinorVersion>

    <AssemblyFileBuildNumber>0</AssemblyFileBuildNumber>

    <AssemblyFileRevision>0</AssemblyFileRevision>

 

 

    <AssemblyBuildNumberType>DateString</AssemblyBuildNumberType>

    <AssemblyBuildNumberFormat>MMdd</AssemblyBuildNumberFormat>

    <AssemblyRevisionType>NoIncrement</AssemblyRevisionType>

    <AssemblyRevisionFormat>0</AssemblyRevisionFormat>

 

    <AssemblyFileBuildNumberType>DateString</AssemblyFileBuildNumberType>

    <AssemblyFileBuildNumberFormat>MMdd</AssemblyFileBuildNumberFormat>

    <AssemblyFileRevisionType>NoIncrement</AssemblyFileRevisionType>

    <AssemblyFileRevisionFormat>0</AssemblyFileRevisionFormat>

 

    <!– Dump the TFS BuildNumber to the Assembly Comment Prop –>

    <AssemblyDescription>$(BuildNumber)</AssemblyDescription>

 

    <!– TF.exe –>

    <TF>&quot;$(TeamBuildRefPath)¥..¥tf.exe&quot;</TF>

    <!– AssemblyInfo file –>

    <AssemblyInfoSpec>AssemblyInfo.*</AssemblyInfoSpec>

  </PropertyGroup> 

5. Set the revision number

By altering the target CheckSettingsForEndToEndIteration, you can use the custom build task you have yet to implement for extracting the revision number from the buildnumber and add it to the assembly version:

  <!– Use the ExtractRevionTask to get the RevionNumber out of the BuildNumber.

       Update the AssemblyInfoTask Properties with the result BuildRevision. –>

  <Target Name="CheckSettingsForEndToEndIteration">

 

    <!–for 2008 use the GetBuildProperties Task to get the BuildNumber –>

    <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)">

      <Output TaskParameter="BuildNumber" PropertyName="BuildNumber"></Output>

    </GetBuildProperties>

 

    <!–  extract the BuildRevision –>

    <ExtractRevisionTask BuildNumber="$(BuildNumber)">

      <Output TaskParameter="BuildRevision" PropertyName="BuildRevision" />

    </ExtractRevisionTask>

 

    <!–  update the AssemblyInfo Props –>

    <CreateProperty Value="$(BuildRevision)">

      <Output TaskParameter="Value" PropertyName="AssemblyRevision"/>

    </CreateProperty>

    <CreateProperty Value="$(BuildRevision)">

      <Output TaskParameter="Value" PropertyName="AssemblyFileRevision"/>

    </CreateProperty>

 

    <!–  just needed if you populate the AssemblyDescription  too like in the sample  –>

    <CreateProperty Value="$(BuildNumber)">

      <Output TaskParameter="Value" PropertyName="AssemblyDescription"/>

    </CreateProperty>

  </Target>

6. Check out and back in all AssemblyInfo.[cs|vb] files from your workspaces

Before you can alter the AssemblyInfo files, you need to let Team Build check them out:

  <!– Use TF to check-out/In the assemblyinfo files to persist updated Version Info –>

  <Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true'">

 

    <!– Set the AssemblyInfoFiles items dynamically –>

    <CreateItem Include="$(SolutionRoot)¥**¥$(AssemblyInfoSpec)">

      <Output ItemName="AssemblyInfoFiles" TaskParameter="Include" />

    </CreateItem>

 

    <Message Text="These AssemblyInfo.* files were found:"/>

    <Message Text ="@(AssemblyInfoFiles)"/>

 

    <Exec WorkingDirectory="$(SolutionRoot)"

    Command="$(TF) checkout &quot;@(AssemblyInfoFiles, '&quot; &quot;')&quot;"/>

  </Target>

 Right after the altered files have been compiled, you can check them back in:

  <Target Name="AfterCompile" Condition="'$(IsDesktopBuild)'!='true'">

    <Exec WorkingDirectory="$(SolutionRoot)"

 

    Command="$(TF) checkin /comment:&quot;Auto-Build: Version Update&quot; /noprompt /override:&quot;Auto-Build: Version Update&quot; &quot;@(AssemblyInfoFiles, '&quot; &quot;')&quot;"/>

  </Target> 

Just in case anything bad happens, there is a way of undoing the changes:

  <!– In case of Build failure, the AfterCompile target is not executed. Undo the changes –>

  <Target Name="BeforeOnBuildBreak" Condition="'$(IsDesktopBuild)'!='true'">

    <Exec WorkingDirectory="$(SolutionRoot)"

    Command="$(TF) undo /noprompt &quot;@(AssemblyInfoFiles, '&quot; &quot;')&quot;"/>

  </Target>

 7. Implement the ExtractRevision custom build task

Simply create a new C# library project with the following class (and add a strong name to it by signing it in the project properties):

namespace ExtractRevision

{

    using Microsoft.Build.Framework;

    using Microsoft.Build.Utilities;

 

    public class ExtractRevisionTask : Task

    {

        public override bool Execute()

        {

            int indexOfDot = buildNumber.LastIndexOf(".");

            if (indexOfDot != -1 & indexOfDot != buildNumber.Length – 1)

            {

                buildRevision = buildNumber.Substring(indexOfDot + 1, buildNumber.Length – (indexOfDot + 1));

            }

            else

            {

                //there is no char following the dot or we can't find a dot

                buildRevision = "0″;

            }

            return true;

        }

 

        private string buildRevision;

        private string buildNumber;

 

        public string BuildNumber

        {

            set { buildNumber = value; }

        }

 

        [Output]

        public string BuildRevision

        {

            get { return buildRevision; }

        }

    }

}

 

You need to check in the .dll file directly into your TeamBuildTypes folder on TFS.

 

Tuesday, June 29, 2010

How to auto-increment assembly version using a custom MSBuild task

The assembly version string has the format “major.minor.build.revision”, such as 2.0.50727.42.  Here is a sample on how to create a custom MSBuild task for Web Deployment Projects  to auto-increment the build and revision portion of your version strings with each build.

Web Deployment Projects provide a way to pre-compile a Visual Studio 2005 Web Site project into a single assembly.  It also allows you to specify the AssemblyFileVersion and AssemblyVersion for this assembly.

These values can be set in the Project Properties dialog of the Web Deployment Project.  Once set the following will be added to the Web Deployment Project file.

  <ItemGroup>  
   <AssemblyAttributes Include="AssemblyFileVersion">  
    <Value>2.0.0.0</Value>  
   </AssemblyAttributes>  
   <AssemblyAttributes Include="AssemblyVersion">  
    <Value>2.0.0.0</Value>  
    <AutoIncrement>true</AutoIncrement>  
   </AssemblyAttributes>  
  </ItemGroup> 

The Microsoft.WebDeployment.targets file includes a target named GenerateAssemblyInfo that will use the @(AssemblyAttributes) item collection defined above to dynamically create an AssemblyInof.cs file.  This file is compiled into an assembly and passed to aspnet_merge.exe using its –copyattrs argument.

This is great if you want to fix the version to a specific value, but what if you want to generate a new build number with every build.  After all the format of version string is “major.minor.build.revision”.

To do this we’ll need to dynamically generate the AssemblyAttributes item collection at build time instead of statically declaring their values in the Web Deployment Project file.

First create a custom MSBuild task.  MSBuild tasks are classes derived from Microsoft.Build.Utilities.Task that override the Execute() method.  You can learn more about writing MSBuild tasks from How To: Write a Task

Here is a sample MSBuild task that will increment build and revision numbers. 

Contents of file IncrementBuildNumber.cs:

using System;  
 using System.IO;  
 using Microsoft.Build.Utilities;  
 using Microsoft.Build.Framework;  
 namespace MyTasks  
 {  
   public class IncrementBuildNumber : Task  
   {  
     string m_fileName;   // Text file containing previous build number  
     long m_buildNumber;   // Build number based on current date. 12/2/2005 would be 51202  
     long m_revisionNumber; // Revision number, increments within a day with each new day starting at 0  
     /// <summary>  
     /// MSBuild entry point into this task.  
     /// </summary>  
     public override bool Execute()  
     {  
       bool bSuccess = true;  
       try  
       {  
         IncrementNumbers();  
         Log.LogMessage(MessageImportance.Normal, "Build {0}.{1}", m_buildNumber, m_revisionNumber);  
       }  
       catch (Exception ex)  
       {  
         // Log Failure  
         Log.LogErrorFromException(ex);  
         Log.LogMessage(MessageImportance.High, "Failed to increment Build Number!");  
         bSuccess = false;  
       }  
       return bSuccess;  
     }  
     /// <summary>  
     /// Task argument set MSBuild project file  
     /// </summary>  
     [Required]  
     public string File  
     {  
       get { return m_fileName; }  
       set { m_fileName = value; }  
     }  
     /// <summary>  
     /// Task output available to MSBuild  
     /// </summary>  
     [Output]  
     public long BuildNumber  
     {  
       get { return m_buildNumber; }  
       set { m_buildNumber = value; }  
     }  
     /// <summary>  
     /// Task output available to MSBuild  
     /// </summary>  
     [Output]  
     public long RevisionNumber  
     {  
       get { return m_revisionNumber; }  
       set { m_revisionNumber = value; }  
     }  
     /// <summary>  
     /// Increments Build Number and Build Revision  
     /// based on the numbers saved in a text file.  
     /// </summary>  
     private void IncrementNumbers()  
     {  
       // Set build number to current date, 12/02/2005 == 51202  
       DateTime dDate = DateTime.Now;  
       m_buildNumber = dDate.Year % 2000 * 10000;  
       m_buildNumber += dDate.Month * 100;  
       m_buildNumber += dDate.Day;  
       // Defualt build revision to 0  
       m_revisionNumber = 0;  
       // Check for a previous build and revision number  
       if (System.IO.File.Exists(m_fileName))  
       {  
         StreamReader sr = new StreamReader(m_fileName);  
         string previousBuild = sr.ReadLine();  
         sr.Close();  
         string[] previousNumbers = previousBuild.Split('.');  
         if (m_buildNumber == long.Parse(previousNumbers[0]))  
           m_revisionNumber = long.Parse(previousNumbers[1]) + 1;  
       }  
       // Write the current build numbers to the file  
       StreamWriter sw = new StreamWriter(m_fileName);  
       sw.WriteLine(string.Format("{0}.{1}", m_buildNumber, m_revisionNumber));  
       sw.Flush();  
       sw.Close();  
     }  
   }  
 }  

Compile file IncrementBuildNumber.cs into the assembly MyTasks.dll

csc /t:library /r:Microsoft.Build.Utilities.dll;Microsoft.Build.Framework.dll /out:MyTasks.dll IncrementBuildNumber.cs

Copy the MyTasks.dll into the same directory as the Web Deployment Project.

Now that we’ve got our custom MSBuild task we need to modify the Web Deployment Project file to use our new custom task.

You can edit the project file by right clicking on the Web Deployment Project in the solution explorer and selecting “Open Project File” from the shortcut menu.

Once opened add a <UsingTask> between the <Project> and the first <PropertyGroup> to register the new custom IncrementBuildNumber task with MSBuild.

 <!--  
  Microsoft Visual Studio 2005 Web Deployment Project  
  http://go.microsoft.com/fwlink/?LinkId=55111  
 -->  
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
  <UsingTask TaskName="MyTasks.IncrementBuildNumber" AssemblyFile="MyTasks.dll" />  
  <PropertyGroup>  
    …  
  </PropertyGroup>  

Next override the BeforeBuild target with the code below.


 <Target Name="BeforeBuild">  
   <IncrementBuildNumber  
    File = "$(MSBuildProjectDirectory)\BuildNumbers.txt">  
    <Output TaskParameter="BuildNumber" PropertyName="BuildNumber"/>  
    <Output TaskParameter="RevisionNumber" PropertyName="RevisionNumber"/>  
   </IncrementBuildNumber>  
   <CreateItem Include="AssemblyFileVersion" AdditionalMetadata="Value=2.0.$(BuildNumber).$(RevisionNumber)">  
    <Output ItemName="AssemblyAttributes" TaskParameter="Include" />  
   </CreateItem>  
   <CreateItem Include="AssemblyVersion" AdditionalMetadata="Value=2.0.$(BuildNumber).$(RevisionNumber)">  
    <Output ItemName="AssemblyAttributes" TaskParameter="Include" />  
   </CreateItem>  
 </Target>  


In this sample we’re using a BuildNumbers.txt file to store the build numbers from each build.  It is passed to the IncrementBuildNumber task through the File property.  The $(MSBuildProjectDirectory) property is a built in property provided by MSBuild that specifies the directory containing the project file.

The BuildNumber and BuildRevision values are then copied from our custom MSBuild task IncrementBuildNumbers as MSBuild properties using the <Output> tags.
  
 <Output TaskParameter="BuildNumber" PropertyName="BuildNumber"/>  
 <Output TaskParameter="RevisionNumber" PropertyName="RevisionNumber"/>

At this point there are now 2 new MSBuild properties $(BuildNumber) and $(RevisionNumber).  The next step is to dynamically create the AssemblyAttributes version strings using these properties.

   <CreateItem Include="AssemblyFileVersion" AdditionalMetadata="Value=2.0.$(BuildNumber).$(RevisionNumber)">  
    <Output ItemName="AssemblyAttributes" TaskParameter="Include" />  
   </CreateItem>  
   <CreateItem Include="AssemblyVersion" AdditionalMetadata="Value=2.0.$(BuildNumber).$(RevisionNumber)">  
    <Output ItemName="AssemblyAttributes" TaskParameter="Include" />  
   </CreateItem>  

Once created they will be automatically picked up the GenerateAssemblyInfo target provided in the Web Deployment Project.

Be sure to delete the statically declared AssemblyAttributes Items for AssemblyFileVersion and AssemblyVersion.

Delete any of these entries from your project file.

   <AssemblyAttributes Include="AssemblyFileVersion">  
    <Value>2.0.0.0</Value>  
   </AssemblyAttributes>  
   <AssemblyAttributes Include="AssemblyVersion">  
    <Value>2.0.0.0</Value>  
    <AutoIncrement>true</AutoIncrement>  
   </AssemblyAttributes>  

You will get a build error if forget to delete these statically declared values.

Now let’s build and see what happens.




Since this is the first build today it’s getting a build number based on the current date 51202 and the revision is 0.  What happens if we build again?


 Microsoft (R) Build Engine Version 2.0.50727.42  
 [Microsoft .NET Framework, Version 2.0.50727.42]  
 Copyright (C) Microsoft Corporation 2005. All rights reserved.  
 Build started 12/2/2005 8:46:42 AM.  
 __________________________________________________  
 Project "C:\MyProjects\MyWeb\MyWeb_deploy\MyWeb_deploy.wdproj" (default targets):  
 Target BeforeBuild:  
   Build 51202.0  
 Target AspNetCompiler:  
   C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -v /MyWeb -p C:\MyProjects\MyWeb\MyWeb -u -f -d C:\MyProjects\MyWeb\MyWeb_deploy\Debug\  
   Updateing web.config compilation debug = 'True' ...  
   Successfully updated web.config compilation debug = 'True' ...  
 Target GenerateAssemblyInfo:  
   Generating AssemblyInfo ...  
   Setting [assembly: AssemblyFileVersion("2.0.51202.0")]  
   Setting [assembly: AssemblyVersion("2.0.51202.0")]  
   Successfully Generated AssebmlyInfo ...  
   C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /out:C:\MyProjects\MyWeb\MyWeb_deploy\AssemblyInfo\Debug\AssemblyInfo.dll /target:library C:\MyProjects\MyWeb\MyWeb_deploy\AssemblyInfo\Debug\AssemblyInfo.cs  
 Target AspNetMerge:  
   Running aspnet_merge.exe ...  
   C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0\aspnet_merge.exe C:\MyProjects\MyWeb\MyWeb_deploy\Debug -o MyWeb -copyattrs C:\MyProjects\MyWeb\MyWeb_deploy\AssemblyInfo\Debug\AssemblyInfo.dll -debug  
   Successfully merged 'C:\MyProjects\MyWeb\MyWeb_deploy\Debug'.  
 Build succeeded.  
   0 Warning(s)  
   0 Error(s)  
 Time Elapsed 00:00:10.29  


The build number stays as 51202 but the revision number has incremented to 1.  The revision number will continue to increment for each build during the day then starting tomorrow the build number will change to 51203 and the revision will reset to 0.

This is just one example of how to increment build numbers during a build.  In this case the build numbers are coming from a text file and being auto incremented by a custom MSBuild task.

There are other techniques that you could use.  For example MSBuild also exposes all environment variables from the command shell.  So if you primarily build from a command line or batch build environment you could simply set an environment variable for BuildNumber and RevisionNumber.

c:\set BuildNumber=51202
c:\set RevisionNumber=2

Using this technique you can go back to statically defining your AssemblyAttributes and simply reference the environment variables.

  <ItemGroup>  
   <AssemblyAttributes Include="AssemblyFileVersion">  
    <Value>2.0.$(BuildNumber).$(RevisionNumber)</Value>  
   </AssemblyAttributes>  
   <AssemblyAttributes Include="AssemblyVersion">  
    <Value>2.0.$(BuildNumber).$(RevisionNumber)</Value>  
   </AssemblyAttributes>  
  </ItemGroup> 

While simpler to implement it is not auto-incrementing the revision with each build, instead it’s relying on an external build process to set these values.  MSBuild is an extremely powerful build tool exposing many capabilities.  The techniques you use will vary depending on your needs.


String Format for Double [C#]

String Format for Double [C#]

The following examples show how to format float numbers to string in C#. You can use static method String.Format or instance methods double.ToString and float.ToString.

Digits after decimal point

This example formats double to string with fixed number of decimal places. For two decimal places use pattern „0.00“. If a float number has less decimal places, the rest digits on the right will be zeroes. If it has more decimal places, the number will be rounded.

[C#]

// just two decimal places
String.Format("{0:0.00}", 123.4567);      // "123.46"
String.Format("{0:0.00}", 123.4);         // "123.40"
String.Format("{0:0.00}", 123.0);         // "123.00"
 

Next example formats double to string with floating number of decimal places. E.g. for maximal two decimal places use pattern „0.##“.

[C#]

// max. two decimal places
String.Format("{0:0.##}", 123.4567);      // "123.46"
String.Format("{0:0.##}", 123.4);         // "123.4"
String.Format("{0:0.##}", 123.0);         // "123"
 

Digits before decimal point

If you want a float number to have any minimal number of digits before decimal point use N-times zero before decimal point. E.g. pattern „00.0“ formats a float number to string with at least two digits before decimal point and one digit after that.

[C#]

// at least two digits before decimal point
String.Format("{0:00.0}", 123.4567);      // "123.5"
String.Format("{0:00.0}", 23.4567);       // "23.5"
String.Format("{0:00.0}", 3.4567);        // "03.5"
String.Format("{0:00.0}", -3.4567);       // "-03.5"
 

Thousands separator

To format double to string with use of thousands separator use zero and comma separator before an usual float formatting pattern, e.g. pattern „0,0.0“ formats the number to use thousands separators and to have one decimal place.

[C#]

String.Format("{0:0,0.0}", 12345.67);     // "12,345.7"
String.Format("{0:0,0}", 12345.67);       // "12,346"
 

Zero

Float numbers between zero and one can be formatted in two ways, with or without leading zero before decimal point. To format number without a leading zero use # before point. For example „#.0“ formats number to have one decimal place and zero to N digits before decimal point (e.g. „.5“ or „123.5“).

Following code shows how can be formatted a zero (of double type).

[C#]

String.Format("{0:0.0}", 0.0);            // "0.0"
String.Format("{0:0.#}", 0.0);            // "0"
String.Format("{0:#.0}", 0.0);            // ".0"
String.Format("{0:#.#}", 0.0);            // ""
 

Align numbers with spaces

To align float number to the right use comma „,“ option before the colon. Type comma followed by a number of spaces, e.g. „0,10:0.0“ (this can be used only in String.Format method, not in double.ToString method). To align numbers to the left use negative number of spaces.

[C#]

String.Format("{0,10:0.0}", 123.4567);    // "     123.5"
String.Format("{0,-10:0.0}", 123.4567);   // "123.5     "
String.Format("{0,10:0.0}", -123.4567);   // "    -123.5"
String.Format("{0,-10:0.0}", -123.4567);  // "-123.5    "
 

Custom formatting for negative numbers and zero

If you need to use custom format for negative float numbers or zero, use semicolon separator;“ to split pattern to three sections. The first section formats positive numbers, the second section formats negative numbers and the third section formats zero. If you omit the last section, zero will be formatted using the first section.

[C#]

String.Format("{0:0.00;minus 0.00;zero}", 123.4567);   // "123.46"
String.Format("{0:0.00;minus 0.00;zero}", -123.4567);  // "minus 123.46"
String.Format("{0:0.00;minus 0.00;zero}", 0.0);        // "zero"
 

Some funny examples

As you could notice in the previous example, you can put any text into formatting pattern, e.g. before an usual pattern „my text 0.0“. You can even put any text between the zeroes, e.g. „0aaa.bbb0“.

[C#]

String.Format("{0:my number is 0.0}", 12.3);   // "my number is 12.3"
String.Format("{0:0aaa.bbb0}", 12.3);          // "12aaa.bbb3"
 

 

Monday, June 28, 2010

Pass values and retrieve response from Command Prompt

Pass values and retrieve response from Command Prompt

1.  //using System.Diagnostics;

2.  //using System.IO;

3.   

4.  // Start cmd.exe and pass the "ipconfig /all" command to it

5.  ProcessStartInfo psiOpt = new ProcessStartInfo(@"cmd.exe", @"/C ipconfig /all");

6.  // We don't want to show the Command Prompt window and we want the output redirected

7.  psiOpt.WindowStyle = ProcessWindowStyle.Hidden;

8.  psiOpt.RedirectStandardOutput = true;

9.  psiOpt.UseShellExecute = false;

10. psiOpt.CreateNoWindow = true;

11. // Create the actual process object

12. Process procCommand = Process.Start(psiOpt);

13. // Receives the output of the Command Prompt

14. StreamReader srIncoming = procCommand.StandardOutput;

15. // Show the result

16. MessageBox.Show(srIncoming.ReadToEnd());

17. // Close the process

18. procCommand.WaitForExit();

 

Code Formater

Paste Here Your Source Code
Source Code Formatting Options
1) Convert Tab into Space :
2) Need Line Code Numbering :
3) Remove blank lines :
4) Embeded styles / Stylesheet :
5) Code Block Width :
6) Code Block Height :
7) Alternative Background :
Copy Formatted Source Code
 
Preview Of Formatted Code