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

Implement ComWrappers API for AOT/Trim compatibility #11

Closed
PhantomGamers opened this issue Jun 13, 2023 · 6 comments
Closed

Implement ComWrappers API for AOT/Trim compatibility #11

PhantomGamers opened this issue Jun 13, 2023 · 6 comments

Comments

@PhantomGamers
Copy link

Built-in COM support is required for WmiLight but is not trim compatible.

I know this was discussed in #7, though despite the OP of that issue saying that enabling BuiltInComInteropSupport allowed their app to work with full trimming, in my app I'm getting the following exception:

Exception Info: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Stack:
   at WmiLight.Wbem.IWbemServices.ExecQuery(System.String, System.String, WmiLight.Wbem.WbemClassObjectEnumeratorBehaviorOption, WmiLight.Wbem.IWbemContext, WmiLight.Wbem.IWbemClassObjectEnumerator ByRef)
   at WmiLight.Wbem.IWbemServices.ExecQuery(System.String, System.String, WmiLight.Wbem.WbemClassObjectEnumeratorBehaviorOption, WmiLight.Wbem.IWbemContext, WmiLight.Wbem.IWbemClassObjectEnumerator ByRef)
   at WmiLight.Wbem.IWbemServicesExtensions.ExecQuery(WmiLight.Wbem.IWbemServices, System.String, WmiLight.Wbem.WbemClassObjectEnumeratorBehaviorOption, WmiLight.Wbem.IWbemContext)
   at WmiLight.WmiConnection.InternalExecuteQuery(WmiLight.WmiQuery)
   at WmiLight.WmiConnection.ExecuteQuery(WmiLight.WmiQuery)

and when compiling I get the warning:

ILLink : Trim analysis warning IL2026: Internal.Runtime.InteropServices.ComActivator.GetClassFactoryForTypeInternal(ComActivationContextInternal*): Using member 'Internal.Runtime.InteropServices.ComActivator.GetClassFactoryForType(ComActivationContext)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Built-in COM support is not trim compatible. https://aka.ms/dotnet-illink/com

It does work fine with TrimMode set to partial, however this is not ideal.

At the link given in the trim warning, there is a link to this page which discusses using the ComWrappers api which is Trimming/AOT friendly.

I may try to implement this myself, but I see in #9 that a version 4.0 is in the works so I will wait for that before investigating further.

@MartinKuschnik
Copy link
Owner

Implementing a custom COM Wraper does not seams to be easy. Also because WmiLight targets .Net Standard and ComWrappers is a .NET 5+ runtime feature.

Can you please add the following to your project file and give it a try?

PS: I had to clear the publish dir by hand. Otherwise i got the same error.

<Target Name="ConfigureTrimming" BeforeTargets="PrepareForILLink">
  <ItemGroup>
	<ManagedAssemblyToLink Condition="'%(Filename)' == 'WmiLight'">
            <IsTrimmable>false</IsTrimmable>
	</ManagedAssemblyToLink>

	<ManagedAssemblyToLink Condition="'%(Filename)' == 'netstandard'">
	     <IsTrimmable>false</IsTrimmable>
	</ManagedAssemblyToLink>
  </ItemGroup>
</Target>

@PhantomGamers
Copy link
Author

Implementing a custom COM Wraper does not seams to be easy.

Yeah it seems very annoying. It's in Microsoft's plans to implement a source generator to greatly streamline the process dotnet/runtime#66674, but at this point I doubt it'll be implemented any time soon.

Also because WmiLight targets .Net Standard and ComWrappers is a .NET 5+ runtime feature.

Yes, if I implemented this I would multitarget .net standard and .net 5 (or 6/7, probably just net standard and 6 since 5 is no longer supported and 6 is lts), so that existing apps that depend on WmiLight do not break.

Can you please add the following to your project file and give it a try?

Hm, this did not seem to work for me, I'm getting the same error even after clearing out my publish directory, along with all of the bin/ and obj/ directories. You are saying that you were getting the exact same AccessViolationException from my original post, and that target group fixed it?

@MartinKuschnik
Copy link
Owner

I created a simple .Net 7 Test App: WmiTrimTestApp.zip

Im getting following issue:

...\WmiTrimTestApp\bin\Release\net7.0\publish\win-x64>WmiTrimTestApp.exe
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Repeat 2 times:
--------------------------------
   at WmiLight.Wbem.IWbemServices.ExecQuery(System.String, System.String, WmiLight.Wbem.WbemClassObjectEnumeratorBehaviorOption, WmiLight.Wbem.IWbemContext, WmiLight.Wbem.IWbemClassObjectEnumerator ByRef)
--------------------------------
   at WmiLight.Wbem.IWbemServicesExtensions.ExecQuery(WmiLight.Wbem.IWbemServices, System.String, WmiLight.Wbem.WbemClassObjectEnumeratorBehaviorOption, WmiLight.Wbem.IWbemContext)
   at WmiLight.WmiConnection.InternalExecuteQuery(WmiLight.WmiQuery)
   at WmiLight.WmiConnection.ExecuteQuery(WmiLight.WmiQuery)
   at WmiLight.WmiQuery.GetEnumerator()
   at Program.Main(System.String[])

After editing the Project file it works.

@PhantomGamers
Copy link
Author

PhantomGamers commented Jun 13, 2023

The code you posted didn't work for me, though now I'm thinking it was because I was putting it in the project file of my library which uses WmiLight but I should have actually put it in my application project where the trimming occurs. That did give me an idea though and I just tested this and it appears to work:

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

Of course this only sidesteps the issue by preventing trimming on this, but it's a good enough solution for me until the aforementioned code generator is implemented by MS. I'll have to do more testing after I track down the other trimming issues in my app though.

Thanks for your help!

@MartinKuschnik
Copy link
Owner

dotnet/linker#2991 could fix the issue.

@MartinKuschnik
Copy link
Owner

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

Feedback would be nice.

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