Перейти к содержанию

Создание консольного приложения, использующего API TESSA

Создание консольного приложения, использующего API TESSA

В этом примере мы рассмотрим создание независимого консольного приложения .NET, которое может использоваться в целях интеграции и автоматизации взаимодействия с системой TESSA.

Откройте Visual Studio проектного решения Source\Tessa.Extensions.sln. Создайте папку Applications в контекстном меню Solution Explorer. Далее создайте проект Console Application через контекстное меню в папке, который поместите в подпапку Source\Applications, указав путь в поле Location.

Убедитесь, что в свойствах созданного проекта указана платформа .NET 5.0.

Откройте для редактирования файл проекта .csproj и замените его содержимое таким образом:

<Project Sdk="Microsoft.NET.Sdk">

<Import Project="$(ProjectDir)../../Tessa.targets" /> <Import Project="$(ProjectDir)../../Tessa.Extensions.targets" /> <Import Project="$(ProjectDir)../../Tessa.Runtime.targets" />

<PropertyGroup> <Company>Place your Organization here</Company> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> <RestoreSources>$(RestoreSources);../../Bin/packages;https://api.nuget.org/v3/index.json</RestoreSources> <NoWarn>$(NoWarn);1591</NoWarn> <LangVersion>9</LangVersion> </PropertyGroup>

<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'win-x64'"> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup>

<ItemGroup> <EmbeddedResource Include="..\..\..\Configuration\Localization\*.jlocalization" LinkBase="Resources" />

<None Remove="extensions\**" /> <Content Include="extensions\**" CopyToOutputDirectory="PreserveNewest" />

<None Remove="app.json" /> <None Remove="extensions.xml" /> <None Remove="NLog.config" />

<Content Include="app.json" CopyToOutputDirectory="PreserveNewest" /> <Content Include="extensions.xml" CopyToOutputDirectory="PreserveNewest" /> <Content Include="NLog.config" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup>

</Project>

  1. В теге <Company> укажите название вашей организации, которое будет выводиться на консоль в Copyright-сообщении.

  2. В теге <Version> изменяйте номер версии вашего приложения, который будет выводиться на консоль в Copyright-сообщении. В приведённом примере файла проекта тег отсутствует, и версия синхронизирована с версией расширений из файла Tessa.Extensions.targets.

  3. В проекте указано использование версии языка C# 9.0. Эту версию можно использовать на момент написания этого документа только для платформы .NET 5.0.

  4. В проекте отключены предупреждения об async-методах, которые не содержат конструкции await, по аналогии с проектными расширениями, поскольку это удобно при добавлении методов команд, которые должны быть асинхронными по сигнатуре, но фактически могут быть синхронными.

  5. При публикации приложения на 64-битной платформе Windows будет использована технология ReadyToRun, увеличивающая размер публикуемых файлов, но при этом сокращающая время запуска приложения, что особенно актуально для консольных утилит.

  6. Конфигурационные файлы app.json, extensions.xml, NLog.config, а также папка extensions копируются в выходную папку приложения. Они будут добавлены ниже.

  7. Добавляется несуществующая папка Resources, в которой будут размещены библиотеки локализации в ресурсах скомпилированного приложения.

Перейдите в диалог выбора NuGet-пакетов, для этого в контекстном меню на узле Solution '...' в панели инструментов Solution Explorer выберите пункт Manage NuGet Packages.

Перейдите на вкладку Browse и последовательно установите пакеты Tessa.Linux и Tessa.PostgreSql, выбрав версию пакета, соответствующую версии вашей сборки TESSA. Например, для версии сборки TESSA 3.6.0 с патчем 1 укажите версию пакетов также 3.6.0.1. Не обновляйте пакеты до более новых версий до того, как будет обновлена инсталляция всей платформы (вместе с конфигурацией, базой данных и расширениями).

Note

Даже если вы будете использовать разработанную утилиту на Windows для взаимодействия с СУБД MSSQL, установленные пакеты включают в своих зависимостях базовые пакеты для поддержки Windows и MSSQL. Рекомендуется использовать указанные пакеты, поскольку они также обеспечат кроссплатформенность на Linux и поддержку СУБД PostgreSQL ценой нескольких дополнительных мегабайт в выходной папке.

Скопируйте следующее содержимое в файл Program.cs. Комментариями в коде указаны места, на которые следует обратить внимание.

using System; using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; using NLog; using Tessa.Localization; using Tessa.Platform; using Tessa.Platform.CommandLine; using Tessa.Platform.ConsoleApps;

namespace TessaConsoleApp { internal static class Program { private static readonly Logger logger = LogManager.GetCurrentClassLogger();

public static async Task Main(string[] args) { await TessaPlatform.InitializeFromConfigurationAsync();

await LocalizationManager.InitializeDefaultLocalizationAsync( true, // detectLanguage new ILocalizationService[] { JsonResourceFileLocalizationService.FromEmbeddedResources( Assembly.GetExecutingAssembly(), typeof(Program).Namespace + ".Resources.") });

await ConfigurationManager.GetDefaultAsync();

List<string> probingPathList = AssemblyLoaderHelper.GetActualProbingPathList( AssemblyLoaderHelper.GetProbingPathList(ConfigurationManager.Settings), addRootFolder: true);

AssemblyLoaderHelper.AddAssemblyResolveHandler(probingPathList);

if (logger.IsInfoEnabled && args.Length > 0) { string appName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly()?.Location); if (OperatingSystem.IsWindows()) { appName += ".exe"; }

logger.Info("{0} {1}", appName, string.Join(" ", args.Select(arg => "\"" + arg + "\""))); }

if (args.Length == 0) { args = new[] { "help" }; ConsoleAppHelper.WriteLogo(extraLine: false); }

var commandContext = new CommandContext("root");

// пример регистрации команды без использования расширений и регистраторов [ConsoleRegistrator] commandContext.AddCommand<TextWriter, string>(Hello);

// удалите следующую строку, если не требуется выполнять поиск консольных команд в подключённых расширениях ConsoleRegistratorHelper.FindAndExecute(null, commandContext, out _);

try { await commandContext.ExecuteAsync(args); } catch (Exception ex) { logger.LogException(ex);

await System.Console.Error.WriteLineAsync(Environment.NewLine + ex.Message);

Exception inner = ex.InnerException; if (inner != null) { await System.Console.Error.WriteLineAsync(inner.Message); }

ConsoleAppHelper.EnvironmentExit(ConsoleAppHelper.UnhandledExceptionExitCode); } finally { LogManager.Shutdown(); } }

// пример простой команды: TessaConsoleApp Hello Tessa [Verb("Hello"), Description("Says \"Hello\" to a user.")] public static async Task Hello( [Output] TextWriter output, [Argument, Description("User name to say hello to.")] string userName) { await output.WriteLineAsync($"Hello, {userName}!"); } } }

Также в папке приложения нужен ряд конфигурационных файлов для настройки расширений, логирования и методов подключения к базе данных.

Добавьте файл extensions.xml (Add -> New item -> XML File). Содержимое файла приведено ниже:

<?xml version="1.0" encoding="utf-8" ?> <extensions xmlns="http://syntellect.ru/tessa/include">

<scan path="extensions" /> <include file="Tessa.Extensions.PostgreSql.Server.dll" />

</extensions>

Добавьте файл NLog.config (Add -> New item -> XML File). Содержимое файла приведено ниже:

<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<targets async="true"> <target name="file" xsi:type="File" encoding="utf-8" writeBom="true" fileName="${basedir}/log.txt" /> <target name="queries" xsi:type="File" encoding="utf-8" writeBom="true" fileName="${basedir}/queries.txt" layout="--${longdate}${newline}${message}${newline}GO${newline}" /> <target name="null" xsi:type="Null" formatMessage="false" /> </targets>

<rules> <logger name="SqlQueries" minlevel="Error" writeTo="queries" final="true" /> <logger name="SqlQueries" minlevel="Trace" writeTo="null" final="true" /> <logger name="*" minlevel="Info" writeTo="file" /> </rules>

</nlog>

Добавьте файл app.json (Add -> New item -> JSON File). Содержимое файла приведено ниже, рекомендуем заменить в нём строку подключения к базе данных “default” (строка “migration” может использоваться в типовой команде tadmin MigrationDatabase и может быть удалена, если типовые команды отключены):

{ "ConnectionStrings": { "default": "Server=.\\SQLEXPRESS; Database=tessa; Integrated Security=false; User ID=sa; Password=Master1234; Connect Timeout=200; pooling='true'; Max Pool Size=200; MultipleActiveResultSets=true;", "migration": [ "Host=localhost; Database=tessa; User ID=postgres; Password=Master1234; Pooling=true; MaxPoolSize=100", "Npgsql" ] },

"//ConnectionStrings PostgreSQL": { "default": [ "Host=localhost; Database=tessa; User ID=postgres; Password=Master1234; Pooling=true; MaxPoolSize=100", "Npgsql" ] },

"DataProviders": { "Npgsql": "Npgsql.NpgsqlFactory, Npgsql" },

".if": [ "linux", { "Settings": { "PlatformDependencies": "Tessa.Platform.LinuxTessaPlatformDependencies, Tessa.Linux" } } ],

"Settings": { "BaseAddress": "https://localhost", "InstanceName": "", "OpenTimeout": "00:01:01", "CloseTimeout": "00:01:02", "SendTimeout": "00:40:00",

"ProbingPath": "extensions" } }

Создайте папку extensions, в которой будут расположены проектные Shared-расширения и расширения с консольными командами Console. Добавьте файл extensions.xml (Add -> New item -> XML File). Содержимое файла приведено ниже:

<?xml version="1.0" encoding="utf-8" ?> <extensions xmlns="http://syntellect.ru/tessa/include">

<include file="Tessa.Extensions.Default.Console.dll" /> <include file="Tessa.Extensions.Default.Shared.dll" />

<include file="Tessa.Extensions.Console.dll" /> <include file="Tessa.Extensions.Shared.dll" />

</extensions>

Также вам потребуется копировать в папку extensions файлы расширений, собранные для вашего проекта (они будут автоматически скопированы в выходную папку):

  • Tessa.Extensions.Console.dll

  • Tessa.Extensions.Shared.dll

  • Tessa.Extensions.Default.Console.dll

  • Tessa.Extensions.Default.Shared.dll

Все искомые файлы можно найти, например, в папке Source\Bin\Tessa.Extensions.Console в проектном репозитории после сборки решения. Скопируйте эти файлы в папку (в проводнике Windows, не в IDE).

Для успешной работы API внутри консольного приложения также требуется инициализировать локализацию, указав все строки локализации из папки Configuration\Localization вашего решения. Эти файлы встраиваются в исполняемый файл в момент компиляции и далее инициализируются при запуске приложения в Program.cs. В файле проекта .csproj, который был указан выше в теге <EmbeddedResource> указано местоположение файлов локализации относительно папки проекта.

Папка Configuration уже должна располагаться по указанному пути в репозитории вашего проектного решения:

Вы можете указать другой относительный или абсолютный путь к библиотекам локализации в файле .csproj. Для текущего примера достаточно, чтобы в папке Configuration была только подпапка с локализацией Localization, другие файлы можно не копировать. После компиляции консольному приложению уже не потребуется эта папка, все необходимые ресурсы будут встроены в бинарные файлы приложения.

Для сборок расширений должны быть установлены все их зависимости, которые обычно указываются в файлах проектов .csproj для исходных файлах проектов Shared-расширений и консольных команд: Tessa.Extensions.Default.Console.csproj, Tessa.Extensions.Default.Shared.csproj, и любые зависимости в проектах ваших решений Tessa.Extensions.Console.csproj и Tessa.Extensions.Shared.csproj.

В платформе версии 3.6.0.19 это два дополнительных NuGet-пакета DocumentFormat.OpenXml v2.20.0 и CsvHelper v31.0.2. Установим их:

Мы рекомендуем добавлять такое веб-приложение как проект в solution проектных расширений Tessa.Extensions.sln. Тогда вместо ссылок на .dll и дополнительных зависимостей (DocumentFormat.OpenXml, CsvHelper) можно добавить ссылку на проект, при этом выходной файл проектов с расширениями будет скопирован в сборку, а все зависимые NuGet-пакеты - автоматически установлены.

Консольное приложение перед использованием рекомендуется опубликовать (хотя на компьютере разработчика можно запускать и скомпилированную версию). Для этого добавьте скрипт publish.bat (Add -> New item -> Text File), в свойствах файлах оставьте None и Do Not Copy.

Укажите следующее содержимое скрипта, причём в текстовом редакторе задайте кодировку UTF-8 без BOM (по умолчанию в Visual Studio создаётся файл в кодировке UTF-8 + BOM, что приводит к некорректному выполнению скрипта).

@echo off set BuildPath=bin\Publish rd /S /Q "%BuildPath%">nul 2>&1

dotnet publish -c Release -r win-x64 -o "%BuildPath%" pause

Note

Для публикации приложения для Linux замените win-x64 на linux-x64 в этом примере.

Запустите скрипт publish.bat двойным кликом и дождитесь окончания его выполнения. Предварительно собирать проект в Visual Studio не требуется.

В папке bin\Publish будет расположен собранный проект, который можно скопировать в любую папку и использовать для соответствующей ОС (64-битной Windows или 64-битной Linux). Никаких требований к компьютерам, на которых будет запускаться консольная утилита, не предъявляется, т.е. устанавливать .NET Framework или .NET 5.0 не требуется. Поддерживаемые операционные системы определяются используемой платформой .NET, например, для версии .NET 5.0 требования перечислены в документации Microsoft. Если вы используете API TESSA, то обратитесь к руководству по установке и руководству по установке на Linux для системы TESSA.

Для проверки сервиса без установки, запустите командную строку или окно терминала, перейдите в папку публикации, и выполните команду для exe-файла скомпилированного приложения, например, TessaConsoleApp.exe.

TessaConsoleApp Hello TESSA

В соответствии с примером файла Program.cs для команды Hello будет выведено сообщение:

Hello, TESSA!

Для вывода автоматически генерируемой справки по команде:

TessaConsoleApp Hello --help

В примере также подключаются все стандартные команды, включаемые в утилиту tadmin (как это отключить указано в комментарии в Program.cs). Например, вы можете проверить подключение к базе данных, указанной в конфигурационном файле app.json:

TessaConsoleApp CheckDatabase

Таким образом, мы создали, выполнили сборку и публикацию консольного приложения, которое может использоваться в сценариях автоматизации взаимодействия с системой, при этом мы можем использовать полноценное клиентское и/или серверное API платформы TESSA без ограничений.

Back to top