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.
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.
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.
- 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.
-
- 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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<ItemGroup> <EmbeddedResource Remove="$(UserProfile)\.nuget\packages\txtextcontrol.textcontrol.wpf.sdk\31.0.2\contentFiles\any\any\licenses.licx" /> </ItemGroup> Windows Forms
For Windows Forms, the corresponding licenses.licx file should be removed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<ItemGroup> <EmbeddedResource Remove="$(UserProfile)\.nuget\packages\txtextcontrol.textcontrol.winforms.sdk\31.0.2\contentFiles\any\any\licenses.licx" /> </ItemGroup> This removes the licenses.licx from the embedded resources after the NuGet packages are restored in the Azure pipeline.
- 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.
-
In Azure DevOps, open Artifacts and click Create Feed, provide a name and choose the required Visibility. Confirm with Create.
-
Select the newly created feed and click Connect to Feed:
-
From the list, select NuGet.exe
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.
-
Copy the feed path from the shown config file:
-
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:
-
In the feed overview, the uploaded package should be visible:
Configure NuGet in Project
-
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<?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> -
Replace PersonalAccessToken with a newly created Personal Access Token you can create in Azure DevOps:
-
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.
-
In your project, create a new pipeline and select GitHub:
-
Select your project from your repositories.
-
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters- task: NuGetCommand@2 inputs: command: 'restore' restoreSolution: '**/*.sln' feedsToUse: 'config' Important
If your nuget.config is in another folder or the project subfolder, use the nugetConfigPath property in the yml file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters- task: NuGetCommand@2 inputs: command: 'restore' restoreSolution: '**/*.sln' feedsToUse: 'config' nugetConfigPath: 'myApp/nuget.config' A complete sample azure-pipelines.yml would look like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters# .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)'
Running Pipelines
When creating your pipeline, a first run will be performed automatically. The result should look very similar to this:
Now, every time you check in your code, a new run is performed: