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

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

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

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

Откройте Visual Studio и создайте проект Console App (.NET Core).

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

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

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

<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> <Version>1.0.0</Version> <Company>Place your Organization here</Company> <NoWarn>$(NoWarn);1591</NoWarn> <LangVersion>8</LangVersion> </PropertyGroup>

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

<ItemGroup> <Folder Include="Resources\" /> <EmbeddedResource Include="..\Configuration\Localization\*.tll" 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-сообщении.

  3. В проекте указано использование версии языка C# 8.0. Эту версию можно использовать на момент написания этого документа только для платформы .NET Core 3.1 (или для платформы .NET Core 3.0, которая несовместима с релизом TESSA 3.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.5.0 укажите версию пакетов также 3.5.0. Не обновляйте пакеты до более новых версий до того, как будет обновлена инсталляция всей платформы (вместе с конфигурацией, базой данных и расширениями).

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();

LocalizationManager.InitializeDefaultLocalization( true, // detectLanguage new ILocalizationService[] { ResourceFileLocalizationService.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.IsTraceEnabled && args.Length > 0) { string appName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly()?.Location); if (EnvironmentHelper.IsWindows) { appName += ".exe"; }

logger.Trace("{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);

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

Console.WriteLine(); Console.WriteLine(ex.Message);

Exception inner = ex.InnerException; if (inner != null) { Console.WriteLine(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

Все искомые файлы можно найти, например, в папке Tools\extensions внутри сборки TESSA вашей версии (в примере это 3.5.0). Скопируйте эти файлы в папку (в проводнике Windows, не в IDE).

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

Скопируйте папку Configuration из репозитория вашего проектного решения (или из папки со сборкой) рядом с файлом решения .sln, как показано ниже:

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

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

В платформе версии 3.5.0 это два дополнительных NuGet-пакета DocumentFormat.OpenXml v2.11.3 и CsvHelper v15.0.10. Установим их:

Мы рекомендуем добавлять такое веб-приложение как проект в 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 Core не требуется. Поддерживаемые операционные системы определяются используемой платформой .NET Core, например, для версии .NET Core 3.1 требования перечислены в документации 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