SharpDevelop Community

Get your problems solved!
Welcome to SharpDevelop Community Sign in | Join | Help
in Search

Matt Ward

June 2011 - Posts

  • T4 Templates in SharpDevelop

    SharpDevelop 4.1 now has integrated support for T4 Templates. The T4 code generation engine for MonoDevelop has been used to make this feature possible so a big thanks to Michael Hutchinson for creating this. Features include:

    • Syntax highlighting for T4 templates (.tt and .t4 files).
    • Support for TextTemplatingFileGenerator and TextTemplatingFilePreprocessor custom tools.
    • T4 template errors shown in Errors window.

    Code completion for T4 templates is not currently supported.

    Creating a T4 Template

    Open a project in SharpDevelop, right click the project and select Add, New Item. This will open the New File dialog. There are two T4 templates available, one for C# and one for VB.NET.

    C# T4 template selected in New File dialog

    Select the appropriate file template, give it a name and click the Create button.

    New C# T4 template open in text editor.

    Now you can edit the T4 template. In the example below we have modified the T4 template so it generates the current date and time when it is saved.

    <#@ template language="C#" #> 
    <#@ output extension=".txt" #> 
     
    Date and time: <#= DateTime.Now #>

    When the file is saved a new file will be created. In the Projects window this new file will be a child of the T4 template file.

    File generated from T4 template in Projects window.

    Opening this file in the text editor shows text generated by the T4 template.

    File generated from T4 template open in text editor.

    Creating a Preprocessed T4 Template

    SharpDevelop also supports preprocessed T4 templates. A preprocessed T4 template will create a class which can be used by your application at runtime to generate text. We will take our previous template and convert it to a preprocessed T4 template. To do this select the T4 template file in the Projects window, right click and select Properties. Select the Custom Tool property and change it to be TextTemplatingFilePreprocessor.

    T4 template custom tool property changed to TextTemplatingFilePreprocessor

    Now when you save the T4 template a file will be generated containing a class.

    Preprocessed T4 template generated file.

    This class can then be used in your application to generate text at runtime. Shown below is a simple example of how this class could be used.

    using System; 
     
    namespace MyProject 
    { 
     class Program 
     { 
      public static void Main(string[] args) 
      { 
       MyTextTemplate template = new MyTextTemplate(); 
       string text = template.TransformText(); 
        
       Console.WriteLine(text); 
       Console.ReadLine(); 
      } 
     } 
    }

    The result of running the above code is shown below.

    Preprocessed T4 template class output displayed in Console output.

    For more information on creating T4 templates take a look at Oleg Sych's excellent set of T4 tutorials.

    Posted Jun 26 2011, 06:38 PM by MattWard with 3 comment(s)
    Filed under:
  • Project Templates with NuGet Packages

    At MIX this year Microsoft released a tools update to ASP.NET MVC 3. One of the new features was a set of ASP.NET MVC project templates that install libraries, such as jQuery and Modernizr, as NuGet packages. SharpDevelop 4.1 now includes this feature. Let us take a look at how to create a project template for SharpDevelop that installs NuGet packages.

    Creating a Project Template

    As an example we will create a C# project template that installs NUnit as a NuGet package. To keep things simple we will take a copy of an existing C# project template and modify it rather than creating a template from scratch.

    SharpDevelop's project templates can be found in the C:\Program Files\SharpDevelop\4.1\data\templates\project directory, assuming the default installation directory was not changed. The C# project templates are stored in the CSharp directory.

    C# project templates folder open in Windows Explorer

    Find the Library.xpt file. This file is a class library project template. Make a copy of the Library.xpt file in the same directory and call it UnitTestsProject.xpt. Then open UnitTestsProject.xpt with your favourite text editor.

    First change the name of the template so it can be identified when creating a new project. In the TemplateConfiguration section of the template change the Name and the Description as shown below.

     <TemplateConfiguration> 
      <Name>Unit Tests</Name> 
      <Category>C#</Category> 
      <Icon>C#.Project.Library</Icon> 
      <Description>Creates a Unit Tests project.</Description> 
      <SupportedTargetFrameworks>v2.0;v3.5Client</SupportedTargetFrameworks> 
     </TemplateConfiguration>

    Now we need to get the template to run a command when the project is created. This command will be responsible for installing any NuGet packages defined in the project template. Find the Actions element and add a new RunCommand element as shown below.

     <Actions> 
      <Open filename = "MyClass.cs"/> 
      <RunCommand path="/AddIns/PackageManagement/TemplateCommands/InstallPackages"/> 
     </Actions> 
    

    Now we can define the NuGet packages that will be installed when the project is created. Find the Files element and inside that add a new File element as shown below.

       <File name="packages.config"> 
    <![CDATA[<?xml version="1.0" encoding="utf-8"?> 
    <packages> 
      <package id="NUnit" version="2.5.10.11092" /> 
    </packages> 
    ]]> 
      </File>

    This file is the standard NuGet packages.config file. Inside here you can put any NuGet package that you want the template to install. In the example above the NuGet package version has been specified. If you want to install the latest version of a NuGet package then do not include the version attribute, as shown below.

       <File name="packages.config"> 
    <![CDATA[<?xml version="1.0" encoding="utf-8"?> 
    <packages> 
      <package id="NUnit" /> 
    </packages> 
    ]]> 
      </File>

    Finally save the new project template file. We now have a project template that will install the NUnit NuGet package but we have not defined where the NuGet package needs to be stored. We will look at where the NuGet packages need to be located in the next section.

    Configuring NuGet Package Sources

    By default SharpDevelop will look in the data\templates\packages directory for NuGet packages when creating a new project.

    Project template NuGet packages folder open in Windows Explorer

    So we can add the NUnit NuGet package into this directory. To get the NuGet package you can use the NuGet Package Explorer. From the NuGet Package Explorer's File menu select Open from Feed. In the Select Package dialog search for the NUnit package.

    NUnit package searched for in NuGet Package Explorer

    Then double click the NUnit package to open it. Finally from the File menu select Save As and save the package to the data\templates\packages directory.

    Adding NuGet packages into the packages directory is all you need to do to be able to use the project template however you do not have to use this directory. You can configure where the project templates will look for packages in SharpDevelop's options. From the Tools menu select Options. In the Options dialog select Template Package Sources from the Package Management category.

    Project Template Package Sources Options dialog

    In this dialog you can add and remove package sources. You can configure SharpDevelop to use the official NuGet package repository or another directory. If you specify multiple package sources then all of these will be used as a possible source when the project is created.

    With the source of the NuGet packages configured all that is left for us to do is use the project template.

    Creating a New Project

    Now we can try our new project template. From the File menu select New Solution.

    Unit tests project template with NuGet packages selected in New Project dialog.

    Expand the C# category and select the Unit Tests project template. Give the project a name and location and click the Create button.

    Unit tests project created with NuGet packages and open in SharpDevelop

    The project will then be created and the NUnit NuGet package will be installed too.

    Posted Jun 19 2011, 07:04 PM by MattWard with no comments
    Filed under:
  • Installing NuGet Packages outside of Visual Studio

    There have been discussions about using NuGet outside of Visual Studio as well as an open work item in the NuGet issue tracker. Outside of Visual Studio in this context means using NuGet from the command line. There is support for this already with NuGet.exe so let us take a quick look at what is supported at the moment.

    Currently you can use NuGet.exe to download packages without having to use Visual Studio. You can download a single package:

    nuget install nunit

    You can point NuGet.exe to your packages.config and it will download any missing packages:

    nuget install packages.config

    What NuGet.exe will not do is update your project file (.csproj) nor will it run any PowerShell scripts that the package uses. Which is OK in the majority of cases.

    You can go further than this though. Since SharpDevelop supports updating project files as a proof of concept we have used SharpDevelop to extend NuGet further so now NuGet can support everything it does from within Visual Studio but from the command line. From the command line we are able to install a package, have the project file updated with assembly references and any new files, and finally have any PowerShell scripts included in the NuGet package processed.

    Since NuGet uses PowerShell the simplest approach was to extend the existing PowerShell cmdlets included with SharpDevelop. Now you can write a few lines of PowerShell script to install a NuGet package into a project that has never had a NuGet package before, have the project itself updated and any package PowerShell scripts run. All this from the command line without Visual Studio open.

    Setting Everything Up

    Download the zip file containing the cmdlets and extract the assemblies.

    First you will need to modify the PowerShell configuration. By default PowerShell will run under .NET 2.0 but we need it to run under .NET 4.0 since the cmdlets use .NET 4.0. Create a powershell.exe.config file in the C:\Windows\System32\WindowsPowerShell\v1.0 folder with the following contents:

    <configuration>  
        <startup useLegacyV2RuntimeActivationPolicy="true">  
            <supportedRuntime version="v4.0.30319"/>  
            <supportedRuntime version="v2.0.50727"/>  
        </startup>  
    </configuration>   

    Note that if you are running Windows x64 then you should run the 32 bit version of PowerShell and create a powershell.exe.config file in the C:\windows\syswow64\WindowsPowerShell\v1.0 folder.

    The useLegacyV2RuntimeActivationPolicy attribute is required. For a great explanation of what this attribute is take a look at What is useLegacyV2RuntimeActivationPolicy for? written by Mark Miller.

    To be able to run PowerShell scripts included with a NuGet package the execution policy will need to be changed:

    Set-ExecutionPolicy RemoteSigned -Scope Process

    Now import the Package Management Cmdlets assembly. The command below assumes the assembly is in the current working directory otherwise the full path to the assembly will be needed.

    import-module PackageManagement.Cmdlets.dll

    Now we are ready to use the cmdlets.

    Installing a Package

    First the install-package cmdlet has a new -solution parameter to support specifying the solution.

    install-package nunit -solution MySolution\MySolution.sln

    If you do not specify the project name then the first project in the solution will be used as the default project.

    install-package nunit -solution MySolution.sln -projectname MyProject

    Uninstalling a Package

    To uninstall a package we can use the new -solution parameter.

    uninstall-package nunit -solution MySolution.sln -projectname MyProject

    Updating a Package

    Once again we can specify the solution filename when updating a package.

    update-package nunit -solution MySolution.sln -projectname MyProject

    Ideally we would like to be able to update all projects in the solution in one go however this is not currently implemented.

    Setting a Default Project

    Instead of specifying the solution when running each command you can set a default project with the new Set-Project command.

    set-project MyProject d:\Projects\MyProject\MySolution.sln

    After setting the default project the other commands can be run without the need to specify the -solution parameter or the name of the project.

    Package PowerShell Scripts

    Since SharpDevelop has its own set of DTE objects any PowerShell scripts in the package can be run. Each of the cmdlets described above define the DTE variable before any Powershell scripts included with the package are run.

    Conclusion

    So finally we can now use a single PowerShell script to install packages into an empty project. As a simple example:

    setup.ps1:

    import-module d:\scripts\PackageManagement.Cmdlets.dll 
     
    $solution = "d:\Projects\MyProject\MyProject.sln" 
    set-project MyProject $solution
    
    install-package nunit

    To run this from the command line with PowerShell:

    powershell -ExecutionPolicy RemoteSigned -File d:\projects\MyProject\setup.ps1

    Issues

    If you are using $host.Version then within the PowerShell this will return the PowerShell host version and not the NuGet PowerShell host version.

    Several extra SharpDevelop assemblies are included in the zip file. This could be reduced with some more work.

    The formatting for NuGet packages is not defined so the output is a list of properties for each package object.

    Source Code

    The source code is available on github. It is not a part of SharpDevelop since this was an prototype. So there are no unit tests for the new code and core parts of SharpDevelop have been changed to support the new PowerShell cmdlets.

    [Update - Oct 16, 2012] - Added information on using 32 bit version of PowerShell if using Windows x64

  • NuGet PowerShell Console

    Since the NuGet support in SharpDevelop was previewed back in January development has continued and some new features have been added. One of the new features that we will take a look at now is a new PowerShell console that allows SharpDevelop 4.1 to support installing, updating and uninstalling NuGet packages that contain PowerShell scripts.

    Package Management Console

    The Package Management Console is SharpDevelop's new PowerShell console. It provides several cmdlets that can be used to install, uninstall or update NuGet packages. NuGet packages can contain PowerShell scripts that will automate SharpDevelop and extend the functionality provided by NuGet.

    To open the Package Management Console from the View menu select Tools and then select Package Management Console.

    Package Management Console window

    The Package Source drop down list is used to select the NuGet package repository that will be used by default when running commands. The Default Project drop down list has a list of projects in the currently open solution and is used to select the project that the console will use by default. There is also a clear button which clears the text in the console window.

    Help on the commands can be displayed by typing get-help NuGet. To see detailed help on a specific command type get-help followed by the name of the command. Help on the commands can also be found in the official NuGet Package Manager Console PowerShell Reference. Please note that at the time of writing some of the commands are not available but will be added at some point in the future. The unsupported commands are specified in the Issues section at the end of this blog post.

    Finding NuGet Packages

    To find available NuGet packages from a NuGet package source first select that source in the console's drop down list and use the Get-Package command.

    To look for the NUnit.Sample package:

    Looking for all NUnit NuGet packages in PowerShell Console

    To display the packages installed in the project selected in the drop down list run the Get-Package command without any parameters.

    Getting all installed NuGet packages in the PowerShell console

    Adding NuGet Packages

    To install a package first select the required NuGet package source, then select the project where the package should be installed and then use the Install-Package command.

    Installing a NuGet package with the PowerShell console

    Removing NuGet Packages

    To remove a NuGet package use the Uninstall-Package command.

    Uninstalling a NuGet package with the PowerShell console

    Updating NuGet Packages

    To see packages that have updates available you can run the Get-Package -Updates command. To update a package use the Update-Package command.

    Updating a NuGet package in the PowerShell console

    Add Package Reference Dialog

    The Add Package Reference dialog supports installing, updating or uninstalling a package with PowerShell scripts. If it detects that a PowerShell script needs to be run then the package install, update or uninstall actions will be run in the Package Management Console. If PowerShell is not installed then the package will still be installed but the PowerShell scripts will not be run.

    Package PowerShell Scripts

    There are three PowerShell scripts that if included in a NuGet package will be run.

    • init.ps1 - Runs when a package is first installed in a solution and then every time the solution containing this package is opened.
    • install.ps1 - Runs every time a package is installed.
    • uninstall.ps1 - Runs every time a package is uninstalled.

    More details on these scripts can be found in the NuGet documentation on Creating and Publishing a Package.

    When these PowerShell scripts are run they are passed the package, information about the package such where it will be installed and a project object. The scripts also have access to a global $dte variable which is made available by the PowerShell console. If you are using NuGet within Visual Studio then both the project object passed to a PowerShell script and the DTE object, made available via the $dte variable, are part of the Visual Studio object model and can be used to automate Visual Studio. When using SharpDevelop's PowerShell console these objects are also available and can be used to automate SharpDevelop. To do this SharpDevelop provides its own partial implementation of the Visual Studio object model. SharpDevelop implements a set of classes that provide methods and properties that to PowerShell scripts look like Visual Studio's object model but are not dependent on Visual Studio being installed.

    Since SharpDevelop's implementation of Visual Studio's object model is not a full implementation there are going to be some gaps which will mean a PowerShell script may produce some errors when it is run. If a script tries to use a feature provided only by Visual Studio then that will fail too. Another problem is that if a NuGet package directly references and uses the Visual Studio object model then the package will also not work. So this means whilst a package such as Phil Haack's MoodSwings, which changes the text editor fonts and colours, does work a package such as Steve Sanderson's MvcScaffolding that directly accesses Visual Studio directly does not work.

    Issues

    The Package Management Console does not currently support tab completion.

    The entire Visual Studio object model (DTE) is not implemented so PowerShell scripts that use unimplemented features will fail.

    Multline PowerShell commands are not currently supported in the console window.

    Information messages, such as successfully installing a package, are not displayed in the console window and only errors are displayed. These messages are only available in the Output window.

    The NuGet PowerShell profile is not currently supported.

    The New-Package, Open-PackagePage, Add-BindingRedirect cmdlets are not currently implemented.

    Feedback

    Please report any issues on the SharpDevelop forum or feel free to send me an email.

Powered by Community Server (Commercial Edition), by Telligent Systems
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.