Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not working with native aot: Common Language Runtime detected an invalid program #12

Closed
ivanjx opened this issue Nov 30, 2023 · 26 comments

Comments

@ivanjx
Copy link

ivanjx commented Nov 30, 2023

my code:

        string query = string.Format(
            "SELECT * from Win32_Printer WHERE Name = '{0}'",
            printerName);
        using WmiConnection con = new WmiConnection();
        ushort status = (ushort)PrinterStatus.Unknown;

        foreach (WmiObject process in con.CreateQuery(query))
        {
            status = (ushort)process["PrinterStatus"];
        }

        return (PrinterStatus)status;

the error:

Common Language Runtime detected an invalid program. The body of method 'Void WmiLight.Wbem.WbemLocator..ctor()' is invalid.
System.InvalidProgramException: Common Language Runtime detected an invalid program. The body of method 'Void WmiLight.Wbem.WbemLocator..ctor()' is invalid.
   at Internal.Runtime.TypeLoaderExceptionHelper.CreateInvalidProgramException(ExceptionStringID, String) + 0x40
   at Internal.Runtime.CompilerHelpers.ThrowHelpers.ThrowInvalidProgramExceptionWithArgument(ExceptionStringID, String) + 0x9
   at WmiLight.Wbem.WbemLocator..ctor() + 0x15
   at WmiLight.WmiConnection.Open() + 0x43
   at WmiLight.WmiConnection.InternalExecuteQuery(WmiQuery query) + 0x39
   at WmiLight.WmiConnection.ExecuteQuery(WmiQuery query) + 0x2c

csproj:

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

  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <InvariantGlobalization>true</InvariantGlobalization>
    <EnableWindowsTargeting>true</EnableWindowsTargeting>
    <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
    <PublishAot>true</PublishAot>
  </PropertyGroup>

  <ItemGroup>
    <TrimmerRootAssembly Include="myassemblyname" />
    <TrimmerRootAssembly Include="WmiLight" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
    <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
    <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
    <PackageReference Include="Serilog.Sinks.EventLog" Version="3.1.0" />
    <PackageReference Include="System.Drawing.Common" Version="8.0.0" />
    <PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
    <PackageReference Include="WmiLight" Version="4.0.0" />
  </ItemGroup>

</Project>
@MartinKuschnik
Copy link
Owner

AOT is currently not supported. Lease see #11 for more details.

@MartinKuschnik
Copy link
Owner

I'm working on a new verion that is compatible with AOT. It will take a few days.

@MartinKuschnik
Copy link
Owner

@ivanjx Have a look to the version v5.0.0-pre. Native AOT should work with this version.

Please give me feedback so that I can make the pre-release to a release.

@ivanjx
Copy link
Author

ivanjx commented Dec 4, 2023

thanks a lot @MartinKuschnik the latest pre release version works perfectly in my case!

@ivanjx
Copy link
Author

ivanjx commented Dec 4, 2023

one more thing is it possible to compile the cpp wrapper as a static library so it wont output a dll similar to this AvaloniaUI/Avalonia#9503

@MartinKuschnik
Copy link
Owner

"Static library" means that the library is going to be merged with your final application. This concept doesn't exist in .net. .net supports DLLs only.

Maybe there's a way by using C++ CLI but this would require more work - sorry.

@ivanjx
Copy link
Author

ivanjx commented Dec 4, 2023

the concept does not exists with .net but it does exist with .NET Native AOT.
all i need is just the static .lib version of the cpp wrapper. no C++/CLI involved (and no one should ever use it again).

@MartinKuschnik
Copy link
Owner

Ok, your application that gets compiled to native code could link statically.

Why it is so important for you to have only a single file?

@ivanjx
Copy link
Author

ivanjx commented Dec 4, 2023

easier deployment. also to make sure the dependency will always be there and cannot be easily altered.

@MartinKuschnik
Copy link
Owner

I can add the static lib but does not know how to link it in the project file without using absolute paths.

@ivanjx
Copy link
Author

ivanjx commented Dec 4, 2023

im fine with just be able to compile it myself like i did with skiasharp

@MartinKuschnik
Copy link
Owner

try version 5.0.1-pre

image

@ivanjx
Copy link
Author

ivanjx commented Dec 4, 2023

thanks a lot. i will try it in a few hours.

@MartinKuschnik
Copy link
Owner

For me worked:

<ItemGroup>
  <!-- Generate direct PInvokes for Dependency -->
  <DirectPInvoke Include="WmiLight.Native.dll" />
  <!-- Specify library to link against -->
  <NativeLibrary Include="wbemuuid.lib" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
  <NativeLibrary Include="path to x64 WmiLight.Native.lib " Condition="$(RuntimeIdentifier.StartsWith('win'))" />
</ItemGroup>

@MartinKuschnik
Copy link
Owner

The following works also for me but does not require absolute paths.

<ItemGroup>
  <!-- Generate direct PInvokes for Dependency -->
  <DirectPInvoke Include="WmiLight.Native.dll" />
  <!-- Specify library to link against -->
  <NativeLibrary Include="wbemuuid.lib" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
  <NativeLibrary Include="$(OutputPath)WmiLight.Native.lib" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
</ItemGroup>

The problem with this solution: the .lib files will be copies to the output directory. This is confusing to all other users of the library.

Would it be fine for you if i would locate the .lib files into an other directory. Than you would need to reference to the nuget directory.

@MartinKuschnik
Copy link
Owner

Please try v.5.0.1-pre2...

image

@MartinKuschnik
Copy link
Owner

@ivanjx Works for you?

@ivanjx
Copy link
Author

ivanjx commented Dec 7, 2023

hi @MartinKuschnik

sorry i was tasked with different projects. i have tried your new nuget but it does not seem to copy the lib files into the directory. i grabbed the .lib files manually and it seemed to work but i am still missing the wbemuuid.lib. where can i find this? thanks.

EDIT:
nevermind. it seems that the missing lib file is provided automatically. now my app is truly native and single file with 0 dependencies.

image

@ivanjx
Copy link
Author

ivanjx commented Dec 7, 2023

also for the .lib files there is a warning:

WmiLight.Native.lib(WmiLightNative.obj) : MSIL .netmodule or module compiled with /GL found; restarting link with /LT
  CG; add /LTCG to the link command line to improve linker performance

which can be fixed by following this (i dont know how to do it with just command line yet):

  • go to c/c++ -> All Options.
  • find Whole Program Optimization. change to No.
  • go to c/c++ -> Command Line. add /bigobj.

@MartinKuschnik
Copy link
Owner

@ivanjx Try Version 5.0.2-pre

@MartinKuschnik
Copy link
Owner

@ivanjx Try directly Version 5.1.0

@ivanjx
Copy link
Author

ivanjx commented Dec 8, 2023

@MartinKuschnik thanks! now the warnings are gone. though i still not able to use this $(OutputPath)WmiLight.Native.lib but it is fine as long as i can use the .lib file.

@MartinKuschnik
Copy link
Owner

Nice!

To use $(OutputPath)WmiLight.Native.lib would require to add the .lib to the runtime folder of the NuGet package. But this would effect alos the conumers that does noch linke to the static library.

@ivanjx
Copy link
Author

ivanjx commented Dec 8, 2023

it is okay not to include the .lib at all as long as there is an easy way to compile it myself or just download it.

@MartinKuschnik
Copy link
Owner

@ivanjx Please have a look to Version 5.1.1 and Native AOT deployment.

You should be able to replace

  <!-- Generate direct PInvokes for Dependency -->
  <DirectPInvoke Include="WmiLight.Native.dll" />
  <!-- Specify library to link against -->
  <NativeLibrary Include="wbemuuid.lib" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
  <NativeLibrary Include="path to x64 WmiLight.Native.lib " Condition="$(RuntimeIdentifier.StartsWith('win'))" />

with

    <PublishWmiLightStaticallyLinked>true</PublishWmiLightStaticallyLinked>

@ivanjx
Copy link
Author

ivanjx commented Dec 12, 2023

@MartinKuschnik just tried and it works well. thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants