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

Post your working scripts, libraries and tools
IMEime
Posts: 411
Joined: 20 Sep 2014, 06:15

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

25 May 2015, 00:10

thanks
Last edited by IMEime on 05 Jul 2017, 18:43, edited 1 time in total.
dd900
Posts: 76
Joined: 27 Oct 2013, 16:03

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

03 Aug 2015, 00:10

Wow I wish I would have looked into this sooner. I am wondering if I could get some advice? I'm relatively new to C#.

I am trying to create a class to use XPathNavigator. So far what I have works, but I really don't want to go any further until I get some clarification on a few things.
Here is my code so far:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



1.) How do I handle XPathNavigator properties like innerXML? Do I just create another method that returns the value?
2.) How should I handle XPathNodeIterator? Should I create another class to handle its methods?
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

05 Aug 2015, 22:33

If you're wrapping it to make the usage easier for yourself, then the answers are:
1) However you want to handle them.
2) However you want to handle it.

If you're wrapping it just so that you can use it from AutoHotkey, don't. You can use XPathNavigator directly, just as you're using XPathNav, but obviously with different syntax. They're both .NET-based classes. Use CLR_LoadLibrary to load the System.Xml assembly.
dd900
Posts: 76
Joined: 27 Oct 2013, 16:03

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

06 Aug 2015, 14:18

lexikos wrote:They're both .NET-based classes. Use CLR_LoadLibrary to load the System.Xml assembly.


I figured as much, but I can't get anything to work loading the assemblies directly.

Code: [Select all] [Download] GeSHi © Codebox Plus

asm := CLR_LoadLibrary( "System.Xml" )
XPath := CLR_CreateObject( asm, "XPath" )
xPathDoc := new XPath.XPathDocument("path to xml")
xPathNav := xPathDoc.CreateNavigator()



:headwall: Can't even get MessageBox class to work. What am I doing wrong?

Code: [Select all] [Download] GeSHi © Codebox Plus

asm := CLR_LoadLibrary("System.Windows.Forms")
msg := CLR_CreateObject(asm, "MessageBox")
msg.Show("text")
User avatar
Relayer
Posts: 105
Joined: 30 Sep 2013, 13:09
Location: Delaware, USA

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

06 Aug 2015, 21:17

Hi,

I have a dll that was created in .net and want to expose the functions for use in AutoHotkey. I think this thread provides the tools to do that but I need a jump start. Any suggestions? I have a list of all the classes / functions in the dll. I disassembled it with ildasm.exe.

Relayer
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

06 Aug 2015, 21:37

dd900 wrote:What am I doing wrong?

I can't begin to fathom how you came up with that code. Why are you trying to instantiate a namespace (XPath) and an abstract class (MessageBox)? CLR_CreateObject creates an object, as in new classname. You'd never use new XPath() or new MessageBox() in C#.

CLR.ahk has no equivalent of the using statement, therefore you must always specify the full class name, including namespace.

You can't use AutoHotkey's new operator to instantiate a .NET class. If you could there'd be no need for CLR_CreateObject (just some sensible way to get the namespace).

CLR_CreateObject is just a small wrapper around the various overloads of Assembly.CreateInstance. For instance, CLR_CreateObject(asm, "XPathNav") is the same as asm.CreateInstance_2("XPathNav", true). Method #2 is used so that the name can be case-insensitive (but this overload doesn't accept parameters for the constructor).

To call static methods like MessageBox.Show(), you need to get a reference to a Type object representing the class, then call Type.InvokeMember.

Relayer wrote:I have a dll that was created in .net and want to expose the functions for use in AutoHotkey.

First, load the dll with CLR_LoadLibrary. .NET dlls don't expose functions; they expose classes with static and instance methods. Either instantiate a class with CLR_CreateObject, or call static methods using reflection (starting with the Assembly object returned by CLR_LoadLibrary). Refer to the first post for usage of the CLR_ functions.
dd900
Posts: 76
Joined: 27 Oct 2013, 16:03

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

06 Aug 2015, 23:14

How do I get a reference to the MessageBox class Type?

Code: [Select all] [Download] GeSHi © Codebox Plus

asm := CLR_LoadLibrary( "System.Windows.Forms" )
type := asm.GetType() ;type = System.Reflection.Assembly


I've also tried to create a domain then call domain.Load_2(assemblyName), but the only thing I can get to load is "mscorlib". Anything else just returns a "cannot find" error. Could you maybe provide an example?

Edit: Never mind I got it. Thanks for the Info.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



What is 0x158? I understand what the parameter is, but I don't know how you got the value that is being passed.
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

07 Aug 2015, 00:12

The second parameter is "A bitmask comprised of one or more BindingFlags". 0x158 is a bitwise combination of BindingFlags. The values aren't shown in the documentation, but you can print them with a bit of C#, or use an IL disassembler like IL Spy.
dd900
Posts: 76
Joined: 27 Oct 2013, 16:03

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

07 Aug 2015, 00:40

One more question. How would I get an object reference to System.Windows.Forms.MessageBoxButtons?
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

07 Aug 2015, 19:04

You wouldn't. Enumerations are marshalled as integers, hence 0x158 for the second parameter of InvokeMember.
User avatar
Relayer
Posts: 105
Joined: 30 Sep 2013, 13:09
Location: Delaware, USA

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

07 Aug 2015, 19:35

IL Spy says my dll has "com visible" set to FALSE. Does that make it incompatible with the tools shown in this thread?

Relayer
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

08 Aug 2015, 17:54

No.
iPhilip
Posts: 222
Joined: 02 Oct 2013, 12:21

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

06 Sep 2015, 21:57

Thank you Lexikos! Below is code for sending messages from a Gmail account.

iPhilip

Code: [Select all] [Expand] [Download] (Gmail.ahk)GeSHi © Codebox Plus


Note: If you get an authentication error, try any of the solutions here.

Edit: Added error checking for email addresses.
Windows 7 Pro (64 bit) - AutoHotkey v1.1+ (Unicode 32-bit)
MstrGareth
Posts: 2
Joined: 03 Nov 2015, 22:08

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

03 Nov 2015, 22:20

Hiyas,

I am having a problem getting CLR.ahk working with my project/test and was hoping someone can help me get my head out of my ...... :lol:


my c# dll

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus




My ahk script:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



The results on the f12 key is an empty msgbox, but the f11 runs perfectly.

For some reason I am not getting a return value from the test function and I don't have a clue why.

The FSPixel.dll and CLR.ahk are in the same directory as the ahk script. I am using the most up to date U64 version of ahk as well.

Any help would be appreciated.
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

04 Nov 2015, 03:13

As I have not executed your code, the following is based on educated guesswork:
For some reason I am not getting a return value from the test function and I don't have a clue why.

You are not getting a return value from the function that you are not calling. obj.Test() will return nothing if obj is not an object.
obj := CLR_CreateObject(asm, "FSPixel")
FSPixel is a namespace, not a class. How about FSPixel.FSPixel?
MstrGareth
Posts: 2
Joined: 03 Nov 2015, 22:08

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

04 Nov 2015, 15:10

lexikos wrote:FSPixel is a namespace, not a class. How about FSPixel.FSPixel?



Excellent, I knew it was a stupid newb mistake :)


Thanks..
hotkeyguy
Posts: 115
Joined: 11 Oct 2014, 12:22

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

22 Jul 2016, 11:39

Hello Lexikos,

I'm trying to get your old XPtable example running: .NET Framework Interop - Scripts and Functions. How must I replace function COM_Invoke which is unkown? Your Simple C# example is working.


Many thanks and greetings
hotkeyguy
lexikos
Posts: 5455
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

22 Jul 2016, 19:05

The control can do a lot more than just what my example shows. To do anything useful you're going to have to learn the control's own API and how to use .NET objects via CLR.ahk.

For CLR.ahk v1.2, you basically only need to know how to do a few things:

  1. Load the assembly. This is pretty obvious. Just give CLR_LoadLibrary the assembly name (if it is registered in the Global Assembly Cache) or full path. However, it might fail if not built for the latest .NET version. In that case, you need to call CLR_Start first with the appropriate .NET version. In my case, I just recompiled XPTable since I don't have .NET 1.1 installed.

  2. Create an object. Just call CLR_CreateObject(asm, typename), where asm is the assembly object and typename is the type name, including namespace. Any additional parameters are passed to the object's constructor. If there are none, you can use the standard Assembly.CreateInstance method instead; i.e. asm.CreateInstance(typename).

  3. In a few cases you need to specify parameter types. For instance, AutoHotkey has no boolean type so you may need to use ComObject(0xB, false) and ComObject(0xB, -1) instead.

  4. Call overloaded methods. Unfortunately COM-callable wrappers in .NET don't really support method overloads. Each one is instead explicitly numbered, like CreateInstance, CreateInstance_2, CreateInstance_3. When you call an overloaded method, you need to figure out which number you want. (However, this doesn't apply to calling methods via .NET Reflection.)
Anything else, like calling static methods, is a matter of finding and using the appropriate .NET API (i.e. Reflection). There's an example in CLR_LoadLibrary (calling the static method Assembly.LoadFrom).


As for translating my old example, it's simple:
  • COM_Invoke(xx, "yy") is hopefully very obvious. Since xx is now an object, just do xx.yy or xx.yy().
  • COM_Invoke(xx, "yy=", ...) means an assignment. Since xx is now an object, just do an assignment: xx.yy := ...
  • "+" xx as a COM_Invoke parameter passes the pointer xx as an object. Since xx is now an object and not a pointer, just use xx.
  • COM_Invoke_(xx, yy, ...) accepts parameters in pairs, with the COM variant type (a number) followed by the value. You can just wrap each pair of parameters in a single ComObject( ), as in 11, false -> ComObject(11, false). There's no need to specify the type of an object (9 or 13) or string (8); you can pass the value directly (remove the number).
  • The old version of CLR_CreateObject had usage similar to COM_Invoke_. Again, you can just remove 8,, but replace 11,true with ComObject(11, -1) (the original code should have used -1).
  • COM_Release is no longer needed since we're using object references, not pointers.

Code: [Select all] [Expand] [Download] (XPTable_example.ahk)GeSHi © Codebox Plus

hotkeyguy
Posts: 115
Joined: 11 Oct 2014, 12:22

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

22 Jul 2016, 19:58

Hello Lexikos,

thank you so much for your again superb support! Your updated example is working. For me the .NET Framework Interop is really a new adventure. Thanks again for get me started. Asap some updated links to XPTable will follow.


Greetings
hotkeyguy

Return to “Scripts and Functions”

Who is online

Users browsing this forum: burque505 and 19 guests