.NET Framework Interop (CLR, C#, VB)

Post your working scripts, libraries and tools
sancarn
Posts: 211
Joined: 01 Mar 2016, 14:52

Re: .NET Framework Interop (CLR, C#, VB)

23 Jun 2017, 05:44

evilC wrote:I couldn't work out if it was possible, in the end I just returned an array of strings
Indeed, supposedly you can do list.Cast<object>().ToArray()... But I would assume there must be a way to extract the variables directly...
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: .NET Framework Interop (CLR, C#, VB)

23 Jun 2017, 06:33

sancarn wrote:How do you parse a List object from CLR to AHK?

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Include %A_ScriptDir%\CLR.ahk

code =
(
    Imports System
    Imports System.Collections.Generic
    Class MainClass
        Function TestList() as List(Of String)
            return New List(Of String)(New String(){"This","is","a","list"})
        end function
    end class
)

asm := CLR_CompileVB(code, "System.dll")
obj := CLR_CreateObject(asm,"MainClass")
list := obj.TestList()

ICollection := ComObject(9, ComObjQuery(list, "{DE8DB6F8-D101-3A92-8D1C-E72E5F10E992}"), 1)
IList := ComObject(9, ComObjQuery(ICollection, "{7BCFA00F-F764-3113-9140-3BBD127A96BB}"), 1)
Loop % ICollection.Count()
	MsgBox % IList.Item(A_Index - 1)
sancarn
Posts: 211
Joined: 01 Mar 2016, 14:52

Re: .NET Framework Interop (CLR, C#, VB)

23 Jun 2017, 06:48

qwerty12 wrote:
sancarn wrote:How do you parse a List object from CLR to AHK?

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Include %A_ScriptDir%\CLR.ahk

code =
(
    Imports System
    Imports System.Collections.Generic
    Class MainClass
        Function TestList() as List(Of String)
            return New List(Of String)(New String(){"This","is","a","list"})
        end function
    end class
)

asm := CLR_CompileVB(code, "System.dll")
obj := CLR_CreateObject(asm,"MainClass")
list := obj.TestList()

ICollection := ComObject(9, ComObjQuery(list, "{DE8DB6F8-D101-3A92-8D1C-E72E5F10E992}"), 1)
IList := ComObject(9, ComObjQuery(ICollection, "{7BCFA00F-F764-3113-9140-3BBD127A96BB}"), 1)
Loop % ICollection.Count()
	MsgBox % IList.Item(A_Index - 1)
Well I never! This is great to know!

I myself was looking into [this for a possible solution](https://maul-esel.github.io/tutorials/C ... faces.html) but couldn't find the header file for ICollection. By the way... How did you get/find the IID for ICollection and IList?

EDIT:

I didn't realize that all interfaces and IIDs are stored in HKEY_CLASSES_ROOT\Interface\!! This is really useful, though I need to find a quicker way of searching for it :P Perhaps a function could even be created to query the registry for an interface given by name! :o

Edit 2:

Something along the lines of this:

Code: Select all

findIID(name){
	Loop, Reg, HKEY_CLASSES_ROOT\Interface\, KV
	{
		RegRead, interface, HKEY_CLASSES_ROOT\Interface\%A_LoopRegName%
		if (interface = name)
			return A_LoopRegName
		
	}
}
Last edited by sancarn on 23 Jun 2017, 08:32, edited 3 times in total.
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: .NET Framework Interop (CLR, C#, VB)

23 Jun 2017, 06:59

sancarn wrote:By the way... How did you get/find the IID for ICollection and IList?
I took your idea of using [docs]ComObjType[/docs], but with CLSID as Param2 instead and got given a GUID for Object. When Googling it, the results indicated I could find what I was looking for in mscorlib.tlb, so I used oleview.exe on said file. I then took a guess on IList and ICollection being the appropriate interfaces...
User avatar
evilC
Posts: 4342
Joined: 27 Feb 2014, 12:30

Re: .NET Framework Interop (CLR, C#, VB)

04 Jul 2017, 11:21

Anyone got any ideas why this code throws an error?
Is inheritance not supported?

Code: Select all

c# =
(
    class Foo : Bar {
        public int Test() {
            return 2;
        }
    }
	
	class Bar {
	
	}
)
asm := CLR_CompileC#(c#)
obj := CLR_CreateObject(asm, "Foo")
msgbox % obj.Test()
return
lexikos
Posts: 6176
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: .NET Framework Interop (CLR, C#, VB)

05 Jul 2017, 02:31

Add the public modifier to your classes.
User avatar
evilC
Posts: 4342
Joined: 27 Feb 2014, 12:30

Re: .NET Framework Interop (CLR, C#, VB)

05 Jul 2017, 15:18

Yeah, it wasn't just the lack of public, I rewrote the code as a simple AHK script using dynamic compilation, and obviously I simplified too far...

I tried to repro with another dynamically compiled sample, but I could not. Upon further investigation, there appears to be a difference in behavior between pre-compiled DLLs and dynamically compiled code.

Code: Select all

#SingleInstance force
#NoEnv

#include <CLR>

c# =
(
public class Outer
{
    public InnerOne innerOne = new InnerOne();

    public class InnerOne : InnerBase
    {
        public string Test()
        {
            return "OK";
        }
    }

    public class InnerBase
    {

    }
}
)
asm := CLR_CompileC#(c#)
obj := CLR_CreateObject(asm, "Outer")
msgbox % obj.innerOne.Test()
return

^Esc::
	ExitApp
This code works fine, however if you make a project in VS using the same C# code and compile, then calling obj.innerOne.Test() throws an error.
In the compiled version, if you change public class InnerOne : InnerBase to public class InnerOne, then the problem goes away.
Most odd.

SLN attached
Attachments
ClrTest.zip
(15.2 KiB) Downloaded 63 times
lexikos
Posts: 6176
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: .NET Framework Interop (CLR, C#, VB)

05 Jul 2017, 22:59

My guess is that it has something to do with COM visibility. A quick search turned up some details supporting this:
  • Public classes are COM visible by default.
  • Visual Studio overrides this default, making it false.
https://stackoverflow.com/questions/156 ... m-exposure

See Properties\AssemblyInfo.cs.

Code: Select all

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
I think that some methods used by CLR.ahk bypass COM visibility; e.g. because Assembly and Type are COM visible.
User avatar
evilC
Posts: 4342
Joined: 27 Feb 2014, 12:30

Re: .NET Framework Interop (CLR, C#, VB)

06 Jul 2017, 04:29

OK, that would make some sense, so the difference is in the way VS packages the code.
Will give this a try, thanks.

I am thinking that it may make some sense to have some sort of CLR for AHK cribsheet / docs?
eg nuggets of info like this, and maybe some basic patterns to show people how to achieve some common goals (eg how to do callbacks, stuff like the list example from a couple of posts back, etc)
I am happy to contribute, but am conscious that my lack of depth of knowledge in this area may mean some hokey code or bad assumptions, is anyone else willing to pitch in?
sancarn
Posts: 211
Joined: 01 Mar 2016, 14:52

Re: .NET Framework Interop (CLR, C#, VB)

07 Jul 2017, 14:41

evilC wrote:OK, that would make some sense, so the difference is in the way VS packages the code.
Will give this a try, thanks.

I am thinking that it may make some sense to have some sort of CLR for AHK cribsheet / docs?
eg nuggets of info like this, and maybe some basic patterns to show people how to achieve some common goals (eg how to do callbacks, stuff like the list example from a couple of posts back, etc)
I am happy to contribute, but am conscious that my lack of depth of knowledge in this area may mean some hokey code or bad assumptions, is anyone else willing to pitch in?

This would be extremely handy, I agree.
Would be willing to pitch in but I fear I am more inexperienced than yourself xD

Where to make it? Perhaps on github like JXA cookbook. Somewhere where anyone can just go and edit in some examples and stuff. :)
lexikos
Posts: 6176
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: .NET Framework Interop (CLR, C#, VB)

07 Jul 2017, 16:44

No. I'd rather not have second-rate CLR support built-in, and that's the only kind possible via COM callable wrappers.

Putting that aside, I've said before that I don't even use CLR.ahk, and I have no interest in using .NET. So for me, re-implementing CLR support in a different form with the same limitations would be a complete waste of time.
lexikos
Posts: 6176
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: .NET Framework Interop (CLR, C#, VB)

07 Jul 2017, 17:09

Haven't you tried calling overloaded or static methods? There are also enumerations, static fields, and probably other things that require Reflection or some intermediary .NET code.

Though for static methods, one can possibly wrap the Type in a dynamic object.
slimpickens
Posts: 9
Joined: 04 Jul 2017, 06:41

Re: .NET Framework Interop (CLR, C#, VB)

08 Jul 2017, 08:08

Hi, I'm trying to launch a script which #includes CLR.ahk and I get an error "Functions cannot contain functions" at line 11: CLR_LoadLibrary(AssemblyName, AppDomain=0)
I'm using AHK1.1.26 on 64bit windows.

Any idea?

Thanks!
lexikos
Posts: 6176
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: .NET Framework Interop (CLR, C#, VB)

08 Jul 2017, 21:44

You have mismatched braces in your script, or you have used #include inside a function. (This is not specific to CLR.ahk; it would happen with any file containing a function definition.)
slimpickens
Posts: 9
Joined: 04 Jul 2017, 06:41

Re: .NET Framework Interop (CLR, C#, VB)

09 Jul 2017, 05:15

lexikos wrote:You have mismatched braces in your script, or you have used #include inside a function. (This is not specific to CLR.ahk; it would happen with any file containing a function definition.)
Big Thanks!
I didn't believe it but you where right, kind-of, one of the imported scripts was being treated as commented out.
Mper

Re: .NET Framework Interop (CLR, C#, VB)

06 Oct 2017, 17:00

Thank you very much lexikos, you saved my day with this insane .ahk !

Return to “Scripts and Functions”

Who is online

Users browsing this forum: arcticir, ptpt and 20 guests