How to use 'Microsoft.CognitiveServices.Speech' namespace with Azure Functions? - c#

I'm testing the Microsoft Azure Speech services, specifically trying to use Text-To-Speech. So, I'm using a free layer of Azure, and created a TimeTrigger Azure Function to read an e-mail, traverse through HTML and then call the Speech Service with the SDK Microsoft.CognitiveServices.Speech. I'm using the function.proj to load the nuget packages, loading S22.Imap and HtmlAgilityPack without any issues. But the speech package is triggering an exception:
Unable to load DLL 'Microsoft.CognitiveServices.Speech.core.dll' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E).
Am I able to use this package in an Azure Function? If so, what am I doing wrong?
I tried to remove the <PackageReference Include="Microsoft.CognitiveServices.Speech" Version="1.6.0" /> line from function.proj and deleted project.assets.json to reload the package but it didn't work.
This is my function.proj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="S22.Imap" Version="3.6.0" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.9" />
<PackageReference Include="Microsoft.CognitiveServices.Speech" Version="1.6.0" />
</ItemGroup>
</Project>
And this is my run.csx:
using System;
using S22.Imap;
using System.Net.Mail;
using HtmlAgilityPack;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using System.Diagnostics;
public static void Run(TimerInfo myTimer, ILogger log)
{
var username = "sample#gmail.com";
var password = "sample";
var subsKey = "sample";
using(ImapClient client = new ImapClient("imap.gmail.com", 993, username, password, AuthMethod.Login, true))
{
IEnumerable<uint> uids = client.Search(SearchCondition.From("sample#sample.com"));
IEnumerable<MailMessage> messages = client.GetMessages(uids);
log.LogInformation($"Count: {messages.Count()}.");
var msg = messages.FirstOrDefault();
if(msg != null)
{
var doc = new HtmlDocument();
doc.LoadHtml(msg.Body);
var paragraphs = doc.DocumentNode.Descendants()
.Where(x => x.Name == "p" && !string.IsNullOrEmpty(x.InnerText.Trim()))
.ToList();
var mailText = string.Empty;
foreach(var par in paragraphs)
mailText += par.InnerText;
if(!string.IsNullOrEmpty(mailText))
{
var config = SpeechConfig.FromSubscription(subsKey, "myregion");
config.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3);
config.SpeechSynthesisLanguage = "pt-BR";
using (var synthesizer = new SpeechSynthesizer(config))
{
using (var result = synthesizer.SpeakTextAsync(mailText).Result)
{
if (result.Reason == ResultReason.SynthesizingAudioCompleted)
{
//Do something with it
}
else if (result.Reason == ResultReason.Canceled)
{
var cancellation = SpeechSynthesisCancellationDetails.FromResult(result);
log.LogError($"CANCELED: Reason={cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
log.LogError($"CANCELED: ErrorCode={cancellation.ErrorCode}");
log.LogError($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
}
}
}
}
}
}
}
}

You could try to delete the function.proj then recreate one and add Microsoft.CognitiveServices.Speech at first.
Make sure the Microsoft.CognitiveServices.Speech.core.dll has been installed in win-x86 and win-x64. Please refer to this issue.

Mark as perquisite
When you publish mark Visual c++ 14 Runtime Libraries as prerequisite

Related

OpenXml throws a different exception given identical code and similar build configuration for two distinct solutions. Why?

Suppose I have two separate solutions in Visual Studio 2019:
openxml-exceptions.sln
openxml-exceptions-reference.sln
openxml-exceptions.sln
This solution contains two projects:
basic-example: A class library
call-basic-example: A console app
basic-example
The project file is as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>basic_example</RootNamespace>
<ImplicitUsings>disable</ImplicitUsings>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.14.0" />
</ItemGroup>
</Project>
The project also contains SpreadsheetWriterExample.cs:
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using System.Collections.Generic;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Text;
namespace basic_example
{
public class SpreadSheetWriterExample
{
public static void CreateSpreadsheetWorkbook(string filepath)
{
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
Console.WriteLine("creating spreadsheet document");
try
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
{
spreadsheetDocument.Close();
}
}
catch (DirectoryNotFoundException e)
{
Console.WriteLine("DirectoryNotFoundException");
}
catch (ArgumentException)
{
Console.WriteLine("ArgumentException");
}
catch (IOException e)
{
Console.WriteLine("IOException");
}
}
public static void Run()
{
CreateSpreadsheetWorkbook("asd\\da*dw.xlsx");
}
}
}
call-basic-example
The project file is as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>call_basic_example</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\basic-example\basic-example.csproj" />
</ItemGroup>
</Project>
The project also contains Program.cs:
using System;
using basic_example;
namespace call_basic_example
{
class Program
{
static void Main(string[] args)
{
SpreadSheetWriterExample.Run();
}
}
}
openxml-exceptions-reference.sln
This solution contains one project:
basic-example: A console app
basic-example
The project file is as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>basic_example</RootNamespace>
<ImplicitUsings>disable</ImplicitUsings>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.14.0" />
</ItemGroup>
</Project>
The project also includes SpreadSheetWriterExample.cs:
using System;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using System.Collections.Generic;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Text;
namespace basic_example
{
public class SpreadSheetWriterExample
{
public static void CreateSpreadsheetWorkbook(string filepath)
{
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
Console.WriteLine("creating spreadsheet document");
try
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
{
spreadsheetDocument.Close();
}
}
catch (DirectoryNotFoundException e)
{
Console.WriteLine("DirectoryNotFoundException");
}
catch (ArgumentException)
{
Console.WriteLine("ArgumentException");
}
catch (IOException e)
{
Console.WriteLine("IOException");
}
}
public static void Main()
{
CreateSpreadsheetWorkbook("asd\\da*dw.xlsx");
}
}
}
Question:
When I build and run openxml-exceptions.sln with call-basic-example as the startup project, I get DirectoryNotFoundException in the output.
When I build and run openxml-exceptions-reference.sln I get ArgumentException in the output.
I am using the following version of Visual Studio:
Given that I am using the exact same framework version in the class library of openxml-exceptions.sln and the console app of openxml-exceptions-reference.sln and the exact same version of OpenXml, I cannot wrap my head around why the thrown and caught error are different for each solution. As far as I can tell they should be exactly the same, but I am apparently overlooking something fundamental.
Why are the errors thrown different for each solution, given the exact same code, framework version and package version?

.NET 6 WinForm ClickOnce get open arguments

I create a can edit ico file application, I publish with ClickOnce.
I want to click ico file to open my winform application, but my application can't get args(file path).
I try: string fileName = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
but ide show error message: Cannot resolve symbol 'ActivationArguments'
on my ClickOnceProfile.pubxml file:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<FileAssociation Include=".ico">
<Visible>False</Visible>
<Description>ico</Description>
<Progid>ico</Progid>
<DefaultIcon>Resources\ico.ico</DefaultIcon>
</FileAssociation>
</ItemGroup>
</Project>
BTY, if I use this code, I can get arg (not use ClickOnce), but I want to use ClickOnce, please help me.
[STAThread]
static void Main(string[]? args)
{
Application.Run(new Form1(args));
}
public Form1(string[]? args)
{
string filepath = args[0];
}
relevant information:
.NET 6
windows 11
windows forms
Step-1:
   Update the VS2022 to the lastest version.
Step-2:
  Project RightClick => Publish => Publish-Tab => Show All => Setting-tab => Options => Allow Url-Paramaters....
Step-3:
  Copy this file code to you app.
Step-4:
  Write Fllowing code:
var clickOnceInfo = new ClickOnceInfo();
if (!clickOnceInfo.IsNetworkDeployed)
{
MessageBox.Show("设计器只能从Web页面启动,无法独立使用");
return;
}
var query = clickOnceInfo.ActivationUri?.Query ?? "QueryEMPTY";
if (query == "QueryEMPTY")
{
MessageBox.Show("参数设置异常,无法启动设计器");
return;
}

Operation returned an invalid status code 'BadRequest' - Microsoft.Azure.Management.ResourceGraph

Whenever var response line executes it will throw an exception that states
Operation returned an invalid status code 'BadRequest'
The same request that I did in Azure Resource Graph Explorer worked as expected. But for some odd reason, when I do it in a .net console application running a .net 6 framework it tells me its a bad request when in fact it is the correct request. However, after displaying that error it says Principal used: IsAuthenticated:True Type:User TenantId: xxxxx UserPrincipalName: xxxx
Packages installed:
<PackageReference Include="Microsoft.Azure.Management.ResourceGraph" Version="2.1.0" />
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.6.2" />
Program.cs
using Microsoft.Azure.Management.ResourceGraph;
using Microsoft.Azure.Management.ResourceGraph.Models;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Rest;
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
RunResourceGraphQuery(azureServiceTokenProvider).Wait();
if (azureServiceTokenProvider.PrincipalUsed != null)
{
Console.WriteLine($"{Environment.NewLine}Principal used: {azureServiceTokenProvider.PrincipalUsed}");
}
Console.ReadLine();
static async Task RunResourceGraphQuery(AzureServiceTokenProvider azureServiceTokenProvider)
{
Console.WriteLine($"{Environment.NewLine}{Environment.NewLine}Please enter the subscription Id");
var subscriptionId = Console.ReadLine();
List<string> subscriptions = new();
subscriptions.Add(subscriptionId);
try
{
var tokenCredentials = new TokenCredentials(await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false));
var resourceGraphClient = new ResourceGraphClient(tokenCredentials);
var userQueryRequest = new QueryRequest(subscriptions: subscriptions, query: "resources | project name, ['type'] | limit 5", null, null);
var response = resourceGraphClient.Resources(userQueryRequest);
Console.WriteLine(response);
}
catch (Exception exp)
{
Console.WriteLine($"Error message: {exp.Message}");
}
}
I have tried in my environment to recreate the above issue ,and i get the same issue as you are getting.
Created a new project using Console app with .net6 and copied your code to my local .
Installed nuget packages :-
Microsoft.Azure.Management.ResourceGraph" Version="2.1.0"
Microsoft.Azure.Services.AppAuthentication" Version="1.6.2"
This is my .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Management.ResourceGraph" Version="2.1.0" />
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.6.2" />
</ItemGroup>
</Project>
When i tried with your code i get Operation returned an invalid status code 'BadRequest':
After changing the query parameter type query: "resources | project name, ['type'] | limit 5" to this query: "Resources | project name, type | limit 5"
Program.cs:-
using Microsoft.Azure.Management.ResourceGraph;
using Microsoft.Azure.Management.ResourceGraph.Models;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Rest;
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
RunResourceGraphQuery(azureServiceTokenProvider).Wait();
if (azureServiceTokenProvider.PrincipalUsed != null)
{
Console.WriteLine($"{Environment.NewLine}Principal used: {azureServiceTokenProvider.PrincipalUsed}");
}
Console.ReadLine();
static async Task RunResourceGraphQuery(AzureServiceTokenProvider azureServiceTokenProvider)
{
Console.WriteLine($"{Environment.NewLine}{Environment.NewLine}Please enter the subscription Id");
var subscriptionId = Console.ReadLine();
List<string> subscriptions = new();
subscriptions.Add(subscriptionId);
try
{
var tokenCredentials = new TokenCredentials(await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false));
var resourceGraphClient = new ResourceGraphClient(tokenCredentials);
var userQueryRequest = new QueryRequest(subscriptions: subscriptions, query: "Resources | project name, type | limit 5", null, null);
var response = resourceGraphClient.Resources(userQueryRequest);
Console.WriteLine(response);
}
catch (Exception exp)
{
Console.WriteLine($"Error message: {exp.Message}");
}
}
Its working fine at my end:
Still if you are getting the same issue please refer this Microsoft Documentation:Run your first Resource Graph query using .NET Core
For more information refer this MICROSOFT PLAYGROUND : Connecting to the Resource Graph Client via the Resource Graph SDK

Roslyn, Could not load file or assembly System.Runtime

I am new with Roslyn and I am trying to compile my first code at runtime.
The code compile(exe) without error but when i run it throught process.Start() in the concole output appers the error
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
I read that many other people had same problem but the solution here :
https://github.com/dotnet/core/issues/2082
not worked for me
This is the full code of my console app :
using System;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.IO;
using System.Diagnostics;
using Microsoft.Extensions.DependencyModel;
using System.Linq;
namespace TestRoslyn
{
class Program
{
static string code = #"
using System;
namespace First
{
public class Program
{
public static void Main()
{" +
"Console.WriteLine(\"Hello, world!\");"
+ #"
}
}
}
";
static void Main(string[] args)
{
MetadataReference[] _ref = DependencyContext.Default.CompileLibraries
.SelectMany(cl => cl.ResolveReferencePaths())
.Select(asm => MetadataReference.CreateFromFile(asm))
.ToArray();
var syntaxTree = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
var assemblyPath = Path.ChangeExtension(Path.GetTempFileName(), "exe");
var compilation = CSharpCompilation.Create(Path.GetFileName(assemblyPath))
.WithOptions(new CSharpCompilationOptions(OutputKind.ConsoleApplication))
.AddReferences(_ref)
.AddSyntaxTrees(syntaxTree);
var result = compilation.Emit(assemblyPath);
if (result.Success) // Compilation is Success
{
using (Process process = new Process())
{
process.StartInfo.FileName = assemblyPath;
process.Start(); // Here the error appears in the console window
}
}
else
{
System.Diagnostics.Debug.Write(string.Join(
Environment.NewLine,
result.Diagnostics.Select(diagnostic => diagnostic.ToString())
));
}
}
}
}
project file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="5.0.0" />
</ItemGroup>
</Project>
Can someone help me ?

Nuget Update Packages.config in MSBuild BeforeBuild Step

I have been trying to write an MsBuild task to automatically get Nuget packages from a feed url and automatically update the packages.config to update to the latest version.
// ---- Download and install a package at a desired path ----
var sourceUri = new Uri("FEED URL");
// ---- Update the ‘packages.config’ file ----
var packageReferenceFile = new PackageReferenceFile("../../packages.config");
string packagesPath = "../../packages";
IPackageRepository sourceRepository = PackageRepositoryFactory.Default.CreateRepository(sourceUri.ToString());
PackageManager packageManager = new PackageManager(sourceRepository, packagesPath);
foreach (var sourcePackage in sourceRepository.GetPackages().Where(x => x.IsLatestVersion))
{
if (!packageReferenceFile.EntryExists(sourcePackage.Id + " " + sourcePackage.Version, sourcePackage.Version))
{
var oldPackage = packageReferenceFile.GetPackageReferences().FirstOrDefault(x => x.Id.Contains(sourcePackage.Id));
if (oldPackage != null)
{
packageReferenceFile.DeleteEntry(oldPackage.Id, oldPackage.Version);
}
packageManager.InstallPackage(sourcePackage.Id, SemanticVersion.Parse(sourcePackage.Version.ToFullString()));
// Get the target framework of the current project to add --> targetframework="net452" attribute in the package.config file
var currentTargetFw = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
var targetFrameworkAttribute = ((TargetFrameworkAttribute[]) currentTargetFw).FirstOrDefault();
// Update the packages.config file
packageReferenceFile.AddEntry(sourcePackage.GetFullName(),
SemanticVersion.Parse(sourcePackage.Version.ToFullString()), false,
new FrameworkName(targetFrameworkAttribute.FrameworkName));
}
}
This is working fine as a console app and is automatically reading the file correctly and updating the necessary references.
When i try to run this as an MsBuild task I keep running into errors.
An error has occurred during compilation. c:\Users\user\AppData\Local\Temp\dkkg20ya.0.cs(22,11) : error CS0246: The type or namespace name 'NuGet' could not be found (are you missing a using directive or an assembly reference?)
The task factory "CodeTaskFactory" could not be loaded from the assembly "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Build.Tasks.v15.0.dll". The task factory must return a value for the "TaskType" property.
This is the code I have put in the csproj (also moved to the nuget.targets to test)
<Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
<UpdateNugetFiles />
</Target>
<UsingTask TaskName="UpdateNugetFiles" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll" >
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Reflection" />
<Using Namespace="System.Runtime.Versioning" />
<Using Namespace="NuGet" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try {
// ---- Download and install a package at a desired path ----
var sourceUri = new Uri("FEED URL");
// ---- Update the ‘packages.config’ file ----
var packageReferenceFile = new PackageReferenceFile("../../packages.config");
string packagesPath = "../../packages";
IPackageRepository sourceRepository = PackageRepositoryFactory.Default.CreateRepository(sourceUri.ToString());
PackageManager packageManager = new PackageManager(sourceRepository, packagesPath);
foreach (var sourcePackage in sourceRepository.GetPackages().Where(x => x.IsLatestVersion))
{
if (!packageReferenceFile.EntryExists(sourcePackage.Id + " " + sourcePackage.Version, sourcePackage.Version))
{
var oldPackage = packageReferenceFile.GetPackageReferences().FirstOrDefault(x => x.Id.Contains(sourcePackage.Id));
if (oldPackage != null)
{
packageReferenceFile.DeleteEntry(oldPackage.Id, oldPackage.Version);
}
packageManager.InstallPackage(sourcePackage.Id, SemanticVersion.Parse(sourcePackage.Version.ToFullString()));
// Get the target framework of the current project to add targetframework="net452" attribute in the package.config file
currentTargetFw = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
var targetFrameworkAttribute = ((TargetFrameworkAttribute[]) currentTargetFw).FirstOrDefault();
// Update the packages.config file
packageReferenceFile.AddEntry(sourcePackage.GetFullName(),
SemanticVersion.Parse(sourcePackage.Version.ToFullString()), false,
new FrameworkName(targetFrameworkAttribute.FrameworkName));
}
}
return true;
}
catch (Exception ex) {
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
Any ideas on how to resolve this as cannot seem to find a solution.
Overall what to run this a pre step on a CI build to keep nugets up to date.
Thanks
Tim
Just call
nuget restore "your_solution.sln"
Don't reinvent the wheel by writing it in C# code.
Nuget Update Packages.config in MSBuild BeforeBuild Step
Not sure where your code issue comes from. It may be simpler just use NuGet.exe to restore and update the solution instead of trying to use C# code.
So you could add following nuget command line in the MSBuild BeforeBuild Step
<Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
<Exec Command="$(YourNuGetPath)\nuget.exe restore "$(YouSolutionPath)\YourSolution.sln" -PackagesDirectory "$(YouPackagePath)\packages"" />
<Exec Command="$(YourNuGetPath)\nuget.exe update "$(YouSolutionPath)\YourSolution.sln"" />
</Target>
Note: If you are using Visual Studio, Visual Studio will automatically check the missing packages during the build and restore them: Package Restore.
Hope this helps.

Categories

Resources