Since Version 32.0 SP2: Obsolete Article

This article outdated. With the release of TX Text Control 32.0 SP2, new features have been introduced that make parts of this tutorial obsolete. If you are using version 32.0 SP2 or later, please read the following article.

Azure Pipelines with TX Text Control .NET for WPF and Windows Forms 32.0 with Azure DevOps and Artifacts

Important Notice

This article explains how to use build servers with TX Text Control .NET for WPF and Windows Forms using .NET 6 or better. If you are using TX Text Control .NET Server for ASP.NET, please use the following tutorial

Compiling TX Text Control .NET Server 31.0 with Azure DevOps and Artifacts

Continuous integration (CI) is a development practice in which every check-in is verified by an automated build, allowing teams to identify problems early.

With Azure DevOps, Microsoft provides services for teams to share code and track their work. A key feature is continuous integration support for projects called Azure Pipelines. These hosted build agents can build projects on the fly or based on your specifications.

Azure Pipelines

Import Licensing Information

Text Control products are licensed on a per-developer basis. Each developer who uses our products must have their own, assigned license. If you are using a build server, all developers who check-in code, that uses TX Text Control classes, need their own license.

On hosted build machines, such as Azure DevOps, third-party software required to compile the license into the application cannot be installed. To use hosted build agents, the license must be manually compiled and embedded as an embedded resource.

Preparing the Project

Assuming you have already created a Windows Forms App or WPF Application (.NET 6) project using TX Text Control, the following steps are required to prepare the project for Azure Pipelines. In this example, we'll use GitHub as the source of the pipeline, but that's completely independent and doesn't affect the preparation of the project.

  1. Building the License File

    In this step, we will manually compile the license file once to embed it into the project.

    • Open a Visual Studio Command Prompt, change the current directory to your project folder and type in the following command, replacing MyApplication with your assembly name:

      lc.exe /target:MyApplication.dll /complist:"%UserProfile%\.nuget\packages\txtextcontrol.textcontrol.wpf.sdk\31.0.2\contentFiles\any\any\licenses.licx" /i:"C:\Program Files\Text Control GmbH\TX Text Control 31.0.NET for WPF\Assembly\TXTextControl.Server.dll" /i:"C:\Program Files\Text Control GmbH\TX Text Control 31.0.NET for WPF\Assembly\TXTextControl.WPF.dll"

      Important

      • The DLL(s) listed after the /i switch must be referenced from the TX Text Control installation path.
      • The licenses.licx file must be referenced from the NuGet package source. The above example uses version 31.0.2 (SP2). Replace the path and version number based on the version you are using.
      • This example uses TX Text Control .NET for WPF. If you are using Windows Forms, change the NuGet path to the Windows Forms package. The command for Windows Forms should be modified accordingly:

        lc.exe /target:MyApplication.dll /complist:"%UserProfile%\.nuget\packages\txtextcontrol.textcontrol.winforms.sdk\31.0.2\contentFiles\any\any\licenses.licx" /i:"C:\Program Files\Text Control GmbH\TX Text Control 31.0.NET for Windows Forms\Assembly\TXTextControl.Server.dll" /i:"C:\Program Files\Text Control GmbH\TX Text Control 31.0.NET for Windows Forms\Assembly\TXTextControl.Windows.Forms.dll"

      The license compiler will generate the 'MyApplication.dll.licenses' resource file in the project's root folder. By default, the license compiler will add the namespace to the filename.

    • Rename the generated resource file to dll.licenses.

    • Back in Visual Studio, select the project in the Solution Explorer and choose Add Existing Item.... Browse for the created license file, select it and confirm with Add.

    • Select the newly added file dll.licenses and change the property Build Action to Embedded resource.

  2. Removing the licenses.licx

    Open the MyApplication.csproj (MyApplication is your application name) by selecting the project in the Solution Explorer in order to choose Project -> Edit Project File from the main menu.

    Add the following ItemGroup to the project file:

    <ItemGroup>
    <EmbeddedResource Remove="$(UserProfile)\.nuget\packages\txtextcontrol.textcontrol.wpf.sdk\31.0.2\contentFiles\any\any\licenses.licx" />
    </ItemGroup>
    view raw test.csproj hosted with ❤ by GitHub

    Windows Forms

    For Windows Forms, the corresponding licenses.licx file should be removed.

    <ItemGroup>
    <EmbeddedResource Remove="$(UserProfile)\.nuget\packages\txtextcontrol.textcontrol.winforms.sdk\31.0.2\contentFiles\any\any\licenses.licx" />
    </ItemGroup>
    view raw test.csproj hosted with ❤ by GitHub

    This removes the licenses.licx from the embedded resources after the NuGet packages are restored in the Azure pipeline.

  3. Set Platform Target to 64bit

    Select the project in the Solution Explorer and choose Project -> Properties, open the tab Build and set the Platform target to x64.

Uploading NuGet Packages to Artifacts

The required TX Text Control NuGet packages are installed with the developer license setup in the private, local "Text Control Offline Packages" source. Since Azure pipelines don't have access to this package source and Text Control NuGet packages are not listed on NuGet.org, the required packages must be uploaded to Azure Artifacts. Artifacts is an Azure service for creating public and private package feeds needed to build the project.

  1. In Azure DevOps, open Artifacts and click Create Feed, provide a name and choose the required Visibility. Confirm with Create.

    Azure Pipelines

  2. Select the newly created feed and click Connect to Feed:

    Azure Pipelines

  3. From the list, select NuGet.exe

    Azure Pipelines

    Important

    To use NuGet.exe with Azure Artifacts, you'll need a recent version of NuGet (4.8.0.5385+) and the Azure Artifacts credential provider. If you've installed Visual Studio (v15.9-preview1 or later), including the Build Tools edition, you already have the credential provider and you should just download the latest NuGet to a directory on your PATH and outside of your repository.

  4. Copy the feed path from the shown config file:

    Azure Pipelines

  5. Open an elevated (developer) command prompt and push the Text Control NuGet package using the following command. Replace the src string with the string copied in the previous step.

    nuget.exe push "C:\Program Files (x86)\Text Control GmbH\NuGetPackages\txtextcontrol.textcontrol.winforms.sdk.31.0.2.nupkg" -src "https://textcontrol.pkgs.visualstudio.com/Test/_packaging/MyPackages/nuget/v3/index.json" -ApiKey AzureDevOps

    Download NuGet

    The NuGet.exe CLI is not automatically installed by Visual Studio and can be downloaded directly here:

    https://www.nuget.org/downloads

  6. In the feed overview, the uploaded package should be visible:

    Azure Pipelines

Configure NuGet in Project

  1. In your Visual Studio project, create a new file in the project's root folder named nuget.config and copy the following configuration into it:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <packageSources>
    <clear />
    <add key="MyPackages" value="https://pkgs.dev.azure.com/textcontrol/Test/_packaging/MyPackages/nuget/v3/index.json" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    </packageSources>
    <packageSourceCredentials>
    <MyPackages>
    <add key="Username" value="123" />
    <add key="ClearTextPassword" value="PersonalAccessToken" />
    </MyPackages>
    </packageSourceCredentials>
    </configuration>
    view raw nuget.config hosted with ❤ by GitHub
    • Replace PersonalAccessToken with a newly created Personal Access Token you can create in Azure DevOps:

      Azure Pipelines

    • Replace the first packageSources key (MyPackages in this sample) with your created package source in Azure Artifacts.

Create Azure Pipeline

Assuming you are using GitHub as your repository, commit and push your project. Now it is time to create your pipeline in Azure DevOps.

  1. In your project, create a new pipeline and select GitHub:

    Azure Pipelines

  2. Select your project from your repositories.

  3. In this step, you can review the created pipeline YAML. Make sure that the NuGet restore command is using the feed (feedsToUse) from the created config file. The following task can be used to configure that:

    - task: NuGetCommand@2
    inputs:
    command: 'restore'
    restoreSolution: '**/*.sln'
    feedsToUse: 'config'
    view raw azure.yml hosted with ❤ by GitHub

    Important

    If your nuget.config is in another folder or the project subfolder, use the nugetConfigPath property in the yml file:

    - task: NuGetCommand@2
    inputs:
    command: 'restore'
    restoreSolution: '**/*.sln'
    feedsToUse: 'config'
    nugetConfigPath: 'myApp/nuget.config'
    view raw test.yml hosted with ❤ by GitHub

    A complete sample azure-pipelines.yml would look like this:

    # .NET Desktop
    # Build and run tests for .NET Desktop or Windows classic desktop solutions.
    # Add steps that publish symbols, save build artifacts, and more:
    # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net
    trigger:
    - master
    pool:
    vmImage: 'windows-latest'
    variables:
    solution: '**/*.sln'
    buildPlatform: 'Any CPU'
    buildConfiguration: 'Release'
    steps:
    - task: NuGetToolInstaller@1
    - task: NuGetCommand@2
    inputs:
    command: 'restore'
    restoreSolution: '**/*.sln'
    feedsToUse: 'config'
    nugetConfigPath: 'yourAppName/nuget.config'
    - task: VSBuild@1
    inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    - task: VSTest@2
    inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    view raw test.yml hosted with ❤ by GitHub

Running Pipelines

When creating your pipeline, a first run will be performed automatically. The result should look very similar to this:

Azure Pipelines

Now, every time you check in your code, a new run is performed:

Azure Pipelines