JumpList PublishAOT
Hello, I'm creating an Avalonia app and it support PublishAOT build
I would like to add JumpList support to it but I'm not able to make it work after the AOT build.
I tried to use Vanara (https://github.com/dahall/Vanara/) but it stop working as soon as set PublishAOT=true with an InvalidProgramException.
I also tried to use CsWin32 (https://github.com/microsoft/CsWin32/discussions) hoping to have a more modern com support. But I don't have the knowledge to use this low level api.
I tried Avalonia.Win32.JumpLists nuget package too without much more success.
Any idea on how to make it work?
GitHub
GitHub - dahall/Vanara: A set of .NET libraries for Windows impleme...
A set of .NET libraries for Windows implementing PInvoke calls to many native Windows APIs with supporting wrappers. - dahall/Vanara
GitHub
microsoft CsWin32 · Discussions
Explore the GitHub Discussions forum for microsoft CsWin32. Discuss code, ask questions & collaborate with the developer community.
75 Replies
you will have to write the bindings to the COM interfaces yourself for the time being i think
what you'll need to do is go to Vanara (or whichever libary you prefer), go look for the COM interfaces that define the jump list API (the
ComImport
ones), copy them into your project, and convert them to https://learn.microsoft.com/en-us/dotnet/standard/native-interop/comwrappers-source-generation. there is an auto-fixer in Visual Studio that can do this for you sometimes
you can probably copy the C# wrapper glue too, and just have them work over the source-generated COM interfaces
it is not trivial if you are not really experienced with this stuff, but i wouldn't say it's difficultthx
Hello again, @reflectronic , I tried what you suggested but without too much success.
I use the comwrappers source gen and reuse code from Vanara, but I have to update the interface definition to remove
[MarshalAsAttribute]
and object
here and there.
The issue is that I don't really know what to replace them with. They are lot of sample available but they all use the unsupported com "syntax". I was able to create COM object from their GUID cslid/iid, cast it to my com interface, call method on it. But even if it does not crash, I don't know if I'm doing it right.
Do you know where I can find some documentation on how to translate C++ header to comwrapper compatible c# syntax ?
In the meantime I created a small launcher app. 60 loc, but 170 Mo as single file 😠But at least it work.for the
[MarshalAs(UnmanagedType.IUnknown)]
you just need to replace it with [MarshalAs(UnmanagedType.Interface)]
they are the same, it's just that the source generator only recognizes one of them
if there are other issues i can figure out what the equivalent should beThank you very much. I will try. (I was not expecting you to answer that fast)
yeah i looked at it yesterday and i noticed that issue but i forgot to say anything about it
sorry
i don't know if there are other issues though i didn't look that deep
I have this interface IObjectArray "92CA9DCD-5622-4bba-A805-5E9F541BD8C9"
Defined as is in vanara
And I get error on
GetAt
and uiIndex
SYSLIB1052 The specified 'MarshalAsAttribute' configuration for the return value of method 'GetAt' is not supported by source-generated COM.If the specified configuration is required, use ComImport
instead
And
SYSLIB1051 The '[In]' attribute is only supported on array parameters.By-value parameters are considered read-only by default. The generated source will not handle marshalling of parameter 'uiIndex'
[In]
should be deleted from anything that isn't an array, yeah. it makes no difference otherwise
and the IUnknown
should be changed to Interface
Do you mean
[return: MarshalAs(UnmanagedType.Interface)]
?right
it's the same fix for all of the
UnmanagedType.IUnknown
applied to object
Ok
Btw do you know if it exists some tool to inspect com object or more globally debug it?
what exactly do you mean by debugging it
once you have the object all you can really do with it is call methods on it
or try casting it to a different interface
it may not even be able to tell you what the class is. it is pretty limited
Ok. I'm felling totally blind with it 😅
is there a specific problem you are having
Yes, but I try to figure out myself first
are you having the same problem with the ComImport version? because if you are not, then it's likely that there's another mistake somewhere
I have now this interface
public partial interface IObjectCollection : IObjectArray
yup, that's another issue
you need to delete all of the
new
methods, the ones that are inherited from IObjectArray
But the error is in the generated code
in ComImport you needed to repeat them
in GeneratedComInterface you must not repeat them
I can just comment the method already in IObjectArray ?
yeah, they are inherited from IObjectArray
Ok cool
My code look like this right now. It build an run without error.
I'm just getting 0 at the end.
Now I need to create some
IShellLinkW
and add them to IObjectCollection
I didn't used GeneratedComClass
yet. I use this (from msdn doc)
I think GeneratedComClass is mean to replace GetOrCreateObjectForComInstance, isn't it?GeneratedComClass
is for the opposite, it's for GetOrCreateComInterfaceForObject
there is nothing like the CoClass
where it will do the CoCreateInstance
for you. so doing it manually is the right way, yesOk, good and bad new at the same time ^^
So nothing different them for IShellLinkW .
Let's try that
I have plenty new error
yes, the StringBuilder will need to be replaced
Yep, and also
PIDL GetIDList();
Ah no, visual studio add itself the import PIDL from vanara.
PIDL
seem to be a wrapper of SafeHandleall of the StringBuilders should be replaced with
let me see why PIDL does not work
PIDL is defined in Vanara
For the StringBuilder, I had to add this too
[assembly:System.Runtime.CompilerServices.DisableRuntimeMarshalling]
I also have some HWND
I thing I can replace it by IntPtr
I also replace some enum by uint
ok, i see the issue with PIDL
you need to change
GeneratedComInterface
to GeneratedComInterface(Options = ComInterfaceOptions.ComObjectWrapper)
to use it
(or any SafeHandle)But where PIDL should be defined?
idk, to be honest it looks like a pain in the ass to copy
does the code actually use it?
I'm checking
because if you don't need it i would just put IntPtr
Yep does not seem to be used for what I need
Ok, I think I have the MVP ready 🤞
It failed
where did it fail
System.Runtime.InteropServices.MarshalDirectiveException: 'Cannot marshal 'parameter #1': Cannot marshal managed types when the runtime marshalling system is disabled.'in CoCreateInstance
hm, yes, the P/Invokes will need to be changed too
use
LibraryImport
instead of DllImport
it is the same deal as the GeneratedComInterface, it is the new source generator versionis it still ok to have
[assembly:System.Runtime.CompilerServices.DisableRuntimeMarshalling]
yes, LibraryImport is designed to work with that
SYSLIB1050 Method 'CoCreateInstance' should be 'static', 'partial', and non-generic when marked with 'LibraryImportAttribute'. P/Invoke source generation will ignore method 'CoCreateInstance'.
yes, instead of
extern
, it needs to be partial
and the class it's inside of needs to be partial
too
it fail in
AddUserTasks
System.ArgumentException: 'Value does not fall within the expected range.'
can you show the full code
Sure, let me remove lot of comments
I commented the SetTitle in CreateTaskListShellObject
But But does not seem to work with varana either. But without error
Also I'm not sure about all clsid guid
To use the SetTitle I need to add a new interface
IPropertyStore
And it have some needed methode with that use some STRUCT typethe SetIconLocation is required according to the documentation
arf
They are not setting it in varana
hm, i guess it's possible that the documentation is wrong
it looks like it says SetTitle is required too, though
that one is more believable
On varana the title is set like this
yes, you will need to use that
and port all of those interfaces and structs
GitHub
Vanara/PInvoke/Ole/Ole32/PropIdl.PROPVARIANT.cs at master · dahall/...
A set of .NET libraries for Windows implementing PInvoke calls to many native Windows APIs with supporting wrappers. - dahall/Vanara
If I use Vanara.PInvoke.Ole32.PROPERTYKEY as is it seem ok from the source gen
but i have on error for PROVARIANT
void SetValue(in Vanara.PInvoke.Ole32.PROPERTYKEY pkey, [In] Vanara.PInvoke.Ole32.PROPVARIANT pv);
is it mentioning the
[In]
? that can also be deleted
uh, waitYep I tried, same error
can you paste the error
oh, it's a class
Ah yes
it should be a struct
that also means you need to change
[In]
to in
, don't just delete itBetter yes
And for GetValue?
[In, Out]
should be
ref
though, looking at the native API, it looks like it should be out
it will work either way in this case, but the out will be more convenient to useThe PROPVARIANT class from vanara is pretty huge
yeah
it might be best to copy it from somewhere else
seems fine
though you need to make sure that you
Marshal.FreeCoTaskMem
once you are done with the variantnice :)
What a ride!
I would never be able to find all of that by myself
I really want to say thank you very much
I hope one day I will have the same level of knowledge as you.
I'm feeling so dumb next to you (even with my 10y of xp in dotnet)
I still neet to check is still work with AOT
and lot of polish
well i'm glad i could help :)
I need to leave, 4am here. And I still need to go to work. Have a good night (or day)
AOT work like a charm
Just to let you know, I published the code as a gist here https://gist.github.com/latop2604/73bd7d8008e7ed925f5713fda9201ced