Using SQLiteAsyncConnection throwing a MissingMethodException - c#

First time using SQLite, opted for SQLite.net-pcl,
I have a PCL library, that I consume from my UWP app, my PCL library has the DBContext class :
public NewspaperDataContext(ISQLitePlatform sqLitePlatform, string applicationPath, string dataBaseName)
{
_sqlConnection = new SQLiteAsyncConnection(()=> new SQLiteConnectionWithLock(sqLitePlatform,
new SQLite.Net.SQLiteConnectionString(Path.Combine(applicationPath, dataBaseName), storeDateTimeAsTicks: false)));
CreateTableAsync(_sqlConnection, typeof(Article)).Result.Wait();
CreateTableAsync(_sqlConnection, typeof(Author)).Result.Wait();
CreateTableAsync(_sqlConnection, typeof(Category)).Result.Wait();
CreateTableAsync(_sqlConnection, typeof(Group)).Result.Wait();
var c = _sqlConnection.Table<Article>();
}
private async Task<Task> CreateTableAsync(SQLiteAsyncConnection asyncConnection, Type table)
{
return asyncConnection.CreateTableAsync<Author>().ContinueWith((results) =>
{
Debug.WriteLine(!results.IsFaulted
? $"Error where creating the {nameof(table)} table !!"
: $"Table {nameof(table)} created sucessfully!");
});
}
I call the NewspaperDataContext from my UWP app like this :
private async void MainPage_OnLoaded(object sender, RoutedEventArgs e)
{
var n = new NewspaperDataContext(new SQLitePlatformWinRT(), ApplicationData.Current.LocalFolder.Path, "LiberteDB");
}
In the NewspaperDataContext constructor at the line :
var c = _sqlConnection.Table<Article>();
A strange MissingMethodException is thrown saying :
An exception of type 'System.MissingMethodException' occurred in
SQLite.Net.Async.dll but was not handled in user code
Additional information: Method not found: 'Void
SQLite.Net.SQLiteConnectionString..ctor(System.String, Boolean,
SQLite.Net.IBlobSerializer, SQLite.Net.IContractResolver)'.
Couldn't find anything related to this error in the internet, please can someone help.

The package sqlite-net-pcl should be added to only to PCL project. If you add it to any other platform such as Android, it will give this MethodMissingException. So, remove the package from other platforms as this package is required only for PCL project. I am giving this answer as I encountered the same issue and found the solution. I encountered this exception while developing apps using Xamarin.Forms.

Related

MAUI Blazor App Microsoft.CognitiveServices.Speech keyword recognition opening custom table error

I was trying to create simple service that listens for keyword from speech. I was using Microsoft.CognitiveServices.Speech ver 1.24.1 and proceeding with official documentation but got error while trying to read KeywordRecognitionodel from file, file is accessible from that path. Also tried relative and absolute path.
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
namespace HandyCook.Services
{
internal class KeyWordRecognizerService
{
public KeyWordRecognizerService()
{
StartRecognizing();
}
private async void StartRecognizing()
{
var audioConfig = AudioConfig.FromDefaultMicrophoneInput();
var recognizer = new KeywordRecognizer(audioConfig);
recognizer.Recognized += (s, e) =>
{
Console.WriteLine($"{e.Result.Text} DETECTED");
};
var stream = await FileSystem.Current.OpenAppPackageFileAsync("XXX.table"); //accessible
//Exception with an error code: 0x8 (SPXERR_FILE_OPEN_FAILED)
var keywordModel = KeywordRecognitionModel.FromFile(Path.Combine(FileSystem.Current.AppDataDirectory, "XXX.table"));
var result = recognizer.RecognizeOnceAsync(keywordModel);
result.Wait();
}
}
}
To reproduce the error just simply create new MAUI Blazor App, add nuget package 'Microsoft.CognitiveServices.Speech 1.24.1', add service as singleton in MauiProgram then inject in Index.razor. I'm pasting also table file and solution explorer view.
table file: https://sendanywhe.re/18U3PXF8

Gradle plugin returning wrong message

I have created a custom gradle plugin - TaskConfigPlugin
Gradle Version: 1.12/2.0 (Can't upgrade as of now due to Org restrictions)
Java Version: 1.8
My Plugin code is as follows - TaskConfigPlugin.java >>
public class TaskConfigPlugin implements Plugin<Project> {
private String taskPrefix;
private Task mainTask;
#Override
public void apply(Project project) {
TaskConfigPluginExtension extension = project.getExtensions()
.create("taskOrder", TaskConfigPluginExtension.class);
this.taskPrefix = extension.getTaskPrefix(); //the taskPrefix fetched is null
this.mainTask = extension.getMainTask(); //mainTask fetched is null
configureTaskOrdering(project);
}
private void configureTaskOrdering(Project project){
// My Logic to order the task using 'dependsOn', 'mustRunAfter' etc
// It uses the 'taskPrefix' to fetch all matching tasks and then
// establish the relationship with the 'mainTask'
}
}
The extension object - TaskConfigPluginExtension.java >>
public class TaskConfigPluginExtension {
private String taskPrefix;
private Task mainTask;
// getters and setters for the above
}
I have added the plugin info in the META-INF/gradle-plugins/TaskConfigPlugin.properties
which contains the full package name of the Plugin.
The plugin is being consumed as follows in my gradle - mainConsumer.gradle
buildscript {
repositories {
flatDir name: 'libs', dirs: 'lib/'
}
dependencies {
classpath ':TaskConfigPlugin:1.0'
}
}
apply plugin: 'TaskConfigPlugin'
task mainConsumer
taskOrder {
taskPrefix = 'setup'
mainTask = mainConsumer
}
Now when I run my consuming gradle mainConsumer.gradle, I see that the taskPrefix and mainTask values fetched are NULL. I understand that they belong to the CONFIGURATION phase and hence the values cannot be fetched earlier. But I tried with the project.afterEvaluate option and that is also NOT working for me.
There are some solutions (hoping they work) in terms of Provider and Property but I can't use them since they have been introduced with higher gradle versions, I guess 4.+
So, is there some solution or workaround for me with gradle 1.12 to fetch the extension values in the CONFIGURATION phase itself ?
Appreciate your response.
Thanks in advance.

System.MissingMethodException: 'Method not found for XmlRpcProxyGen.Create

I'm trying to communicate with a python server using XML-RCP but when I try to compile the following code, the exception "System.MissingMethodException: 'Method not found: 'System.Reflection.Emit.AssemblyBuilder System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess)'.'" displays, I've found no documentation about this issue
using CookComputing.XmlRpc;
using System;
[XmlRpcUrl("http://192.168.5.211:8000")]
public interface FlRPC : IXmlRpcProxy
{
[XmlRpcMethod("add")]
int add(int x, int y);
}
class Program
{
static void Main(string[] args)
{
FlRPC proxy = XmlRpcProxyGen.Create<FlRPC>();
Console.WriteLine(proxy.add(2, 3));
}
}
I just want to skip this issue to continue to work on my project!
If the application you are trying to build is a .NET Core Application the xmlrpcnet package might be exclusively for the .NET Framework.
Try to replace it with Horizon's .NET Core port, Horizon.XmlRpc.Core and see if it helps.

Load NuGet dependencies at runtime

I'm looking for a way to run code by executing the following steps:
Receiving a list of NuGet packages (a list of tuples ("package name", "package version", "path to main class").
Retrieving them in a local directory (cf code sample #1)
Loading them in my program at run-time
Running the main classes by introspection (cf code sample #2)
By now I am struggling with the third step. I can't find out how to load my package at run-time.
My main question are:
How can I find out in which folders were stored the retrieved packages?
How can I load the content of those directories into my program?
Code Sample #1:
private static void getPackageByNameAndVersion(string packageID, string version)
{
IPackageRepository repo =
PackageRepositoryFactory.Default
.CreateRepository("https://packages.nuget.org/api/v2");
string path = "C:/tmp_repo";
PackageManager packageManager = new PackageManager(repo, path);
Console.WriteLine("before dl pkg");
packageManager.InstallPackage(packageID, SemanticVersion.Parse(version));
}
Code sample #2:
private static void loadByAssemblyNameAndTypeName(string assemblyName, string typeName)
{
AppDomain isolationAppDomain = AppDomain.CreateDomain("tmp");
object a = isolationAppDomain.CreateInstanceAndUnwrap(assemblyName, typeName);
Type x = a.GetType();
MethodInfo m = x.GetMethod("Main");
m.Invoke(a, new object[] { });
}
Grab a cup of coffee :)
Downloading the nuget package?
Nuget.Core (nuget package) is a good choice, and here is a snippet of code that I have that should be able to download a nuget package by id and version
var repo = PackageRepositoryFactory.Default
.CreateRepository("https://packages.nuget.org/api/v2");
string path = "c:\\temp";
var packageManager = new PackageManager(repo, path);
packageManager.PackageInstalled += PackageManager_PackageInstalled;
var package = repo.FindPackage("packageName", SemanticVersion.Parse("1.0.0"));
if (package != null)
{
packageManager.InstallPackage(package, false, true);
}
Notice that I plugged an event handler to the PackageInstalled event of the PackageManager class.
How do we load an assembly in an isolated app domain?
Since reflection API does not provide a way to load an assembly in a specific domain, We will create a proxy class that act as a loader in our isolated domain:
public class TypeProxy : MarshalByRefObject
{
public Type LoadFromAssembly(string assemblyPath, string typeName)
{
try
{
var asm = Assembly.LoadFile(assemblyPath);
return asm.GetType(typeName);
}
catch (Exception) { return null; }
}
}
And now, is how to put it all together?
Here comes the complex part:
private static void PackageManager_PackageInstalled(object sender,
PackageOperationEventArgs e)
{
var files = e.FileSystem.GetFiles(e.InstallPath, "*.dll", true);
foreach (var file in files)
{
try
{
AppDomain domain = AppDomain.CreateDomain("tmp");
Type typeProxyType = typeof(TypeProxy);
var typeProxyInstance = (TypeProxy)domain.CreateInstanceAndUnwrap(
typeProxyType.Assembly.FullName,
typeProxyType.FullName);
var type = typeProxyInstance.LoadFromAssembly(file, "<KnownTypeName>");
object instance =
domain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);
}
catch (Exception ex)
{
Console.WriteLine("failed to load {0}", file);
Console.WriteLine(ex.ToString());
}
}
}
Notice that this method is the event handler that gets executed after downloading the nuget package
Also
Note that you will need to replace <KnownTypeName> with the expected type name coming from the assembly (or maybe run a discovery of all public types in the assembly)
Worth noting that I haven't executed this code myself and cannot guarantee that it will work out of the box, and still might need some tweaking. but Hopefully it is the concept that allows you to solve the problem.
Don't do that! You are probably trying to load NuGet content at a customers computer to save some space on distribution of your software. Isn't it that?
The common recommended approach is to download the NuGet content as the second step of an automated build (after downloading the source code), build the software and run the automated tests with the NuGet content you have downloaded. And then distribute the build with the NuGet content you have tested as the complex whole unit.

Unable to call an ATL COM object from .NET framework

I have a COM object called Test and the .rgs files looks as follows. I do see that this class is registered in the registery at the location HKEY_LOCAL_MACHINE>>SOFTWARE>>Classes>>CLSID.
HKCR
{
NoRemove CLSID
{
ForceRemove {17899D17-698D-4781-894C-3BAA80F3D4BB} = s 'Test Class'
{
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
val AppID = s '{D2A47892-4C98-11D6-8C6D-00105A1790CD}'
'TypeLib' = s '{9A887890-4C99-11d6-8C6D-00105A1790CD}'
}
}
}
When I create an instance of this object inside a C++ project it works fine. The code used is:
ATLTRACE( _T( " | CoCreateInstance Test\n" ) );
hr = m_Test.CoCreateInstance(CLSID_Test, NULL, CLSCTX_INPROC_SERVER);
if (FAILED(hr))
CREATE_COM_OBJECT_ERROR(_T("Test"));
However when I try to call this object from .NET application it errors out saying "An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in PatternEditor.exe
Additional information: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))". The code used is as follows:
public partial class MainWindow : Window
{
Main m_Main = new Main();
Test m_Test;
public MainWindow()
{
InitializeComponent();
//This line errors
m_Test = m_Main.Test;
}
}
Usually, the easiest way to use COM objects inside .NET is creating a reference in the project (the tab COM). It will generate a "stub" and you can use as simple .NET code.
Other way is through reflection. This answer has an idea: C# COM and attaching events

Categories

Resources