Page 4 of 8

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

Posted: 06 Mar 2017, 09:35
by evilC
OK, I have it all working now.
Many thanks to Lexikos for releasing CLR and your help on this thread.

I now have my own thread here: https://autohotkey.com/boards/viewtopic ... 19&t=28889

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

Posted: 10 Mar 2017, 15:30
by evilC
Is it possible to use a BoundFunc instead of a class for the handler?

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

Posted: 10 Mar 2017, 18:04
by lexikos
Why ask the question when it's so simple to just change the code and see what happens?

Yes, it's possible.

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

Posted: 10 Mar 2017, 19:08
by evilC
I tried, but I could not get it to work. I guess I did something wrong - it said something like "interface does not support that". I suppose I will have to try again then.

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

Posted: 10 Mar 2017, 21:58
by lexikos
I can't imagine what would cause that.

Modifying my example to use a BoundFunc is very simple:
  • Obviously, if handler (on the C# side) is a BoundFunc, handler.Handle() won't work. Change it to handler() or handler.call().
  • Change util.Test(Handler) to util.Test(Handler.Handle.Bind(Handler)).

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

Posted: 12 Mar 2017, 07:58
by raskun
How to use this when my main ahk script was referencing to calling to another ahk script?

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

Posted: 20 Mar 2017, 10:14
by b0bi
This seems very interesting, but the download link is dead :/

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

Posted: 20 Mar 2017, 11:31
by burque505
Confirming dead link 03/20/17 at 10:31 MST

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

Posted: 20 Mar 2017, 12:36
by evilC
Removed

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

Posted: 20 Mar 2017, 17:04
by evilC
Whee! C# is fun!

I am currently mucking around with Managed Extensibility Framework (MEF). MEF is basically a framework to make it easy to write plugins which can advertise their capabilities etc.

I have a post here if anyone is interested in how to rig up a DLL which can load other DLLs as plugins - it's pretty easy:

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace InputWrapper
{
    public class InputWrappers
    {
        public interface IInputWrapper
        {
            int GetButtonCount();
            bool Subscribe();
        }

        [Export(typeof(IInputWrapper))]
        [ExportMetadata("Name", "SharpDX_DirectInput")]
        public class SharpDX_DirectInput : IInputWrapper
        {
            public int GetButtonCount()
            {
                return 128;
            }

            public bool Subscribe()
            {
                return true;
            }

        }

        [Export(typeof(IInputWrapper))]
        [ExportMetadata("Name", "SharpDX_XInput")]
        public class SharpDX_XInput : IInputWrapper
        {
            public int GetButtonCount()
            {
                return 10;
            }

            public bool Subscribe()
            {
                return true;
            }

        }

        public interface IInputWrapperMetadata
        {
            string Name { get; }
        }
    }

    public class SubscriptionHandler
    {
        [ImportMany(typeof(InputWrappers.IInputWrapper))]
        IEnumerable<Lazy<InputWrappers.IInputWrapper, InputWrappers.IInputWrapperMetadata>> _interfaceMeta;

        public SubscriptionHandler()
        {
            Compose();
            foreach (Lazy<InputWrappers.IInputWrapper, InputWrappers.IInputWrapperMetadata> inputWrapper in _interfaceMeta)
            {
                if (inputWrapper.Metadata.Name == "SharpDX_DirectInput")
                {
                    Console.WriteLine(inputWrapper.Value.GetButtonCount());
                }
            }
            Console.WriteLine();

            Console.ReadKey();
        }

        private void Compose()
        {
            AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
            CompositionContainer container = new CompositionContainer(catalog);
            container.SatisfyImportsOnce(this);
        }
    }
}

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

Posted: 21 Mar 2017, 05:18
by lexikos
The download link was to my Dropbox public folder. Dropbox killed all public folders.

I've replaced the link. (It just links to the download function of the code box at the bottom of my post now.)

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

Posted: 21 Mar 2017, 10:05
by burque505
Thanks, lexikos.

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

Posted: 01 Apr 2017, 11:46
by evilC
I wrote a library that you can load using CLR to get sub-10ms timers in AHK
https://autohotkey.com/boards/viewtopic.php?f=6&t=29957

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

Posted: 26 Apr 2017, 13:36
by iseahound
How would I load a DLL that loads either a 64 bit or 32 bit DLL?

I'm getting a cannot load file or assembly error, and loading the 64-bit DLL directly returns error "'00.dll' could not be opened -- ‘An attempt was made to load a program with an incorrect format."

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

Posted: 01 May 2017, 01:39
by iseahound
Alright. After some extensive testing, code that works fine in PowerShell gives me an error in AHK. Upon loading an external Dll, The object is successfully created using CLR_CreateObject, but any calls to the created object fail. (Ex. obj.Version does not return the version number. Works fine in Powershell).

I tried debugging the object, and the DispatchType and IID fields are blank.

If anyone can help, I'm trying to convert this code. https://github.com/jourdant/powershell-paperless (DLLS are downloaded via powershell script.)

Code: Select all

#include CLR.ahk
tesslibrary := CLR_LoadLibrary(A_ScriptDir "\lib\Tesseract.dll")
tess := CLR_CreateObject(tesslibrary, "Tesseract.TesseractEngine", "lib\tessdata", "eng")
MsgBox % tess.Version
; Error 0x80131509

/* Powershell
Add-Type -Path ".\Lib\Tesseract.dll"
$tesseract = New-Object Tesseract.TesseractEngine("Lib\tessdata", "eng")
$text = $tesseract.Version
Write-Output $text
*/

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

Posted: 03 Jun 2017, 19:57
by sancarn
I am wondering which versions of Windows OS CLR applies to? From general knowledge I know that CLR 4.5 is installed on all Windows 10 operating systems, however I was wondering how far back this goes? CLR 1.0 appears to go back to Windows 98 OS, but I have no idea whether CLR.AHK will work with the functions provided by CLR 1.0. (P.S. I don't expect Windows 98 to be supported... :p)

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

Posted: 06 Jun 2017, 16:52
by evilC
I manged to figure out how to get a message pump going in a C# DLL with no visible GUI.
In this post, I demo using it to allow my code to process RawInput (WM_INPUT) messages, and fire a callback to AHK, though I would imagine this technique would be handy for other things too.
My code uses SharpDX, so that seems to preclude the need for implementing a message processing loop, but the code has links to an article which shows how that is done.

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

Posted: 06 Jun 2017, 17:03
by evilC
@iseahound - have you tried running the AHK script in Scite4AutoHotkey?
I get what looks like exception messages in the output pane when using CLR, so that may yield some useful info.

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

Posted: 23 Jun 2017, 05:33
by sancarn
How do you parse a List object from CLR to AHK?

Code: Select all

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()

msgbox, % ComObjType(list) ; returns VT_DISPATCH
msgbox, % list.count() ; VB.NET methods don't return values?
msgbox, % list.item(0) ; ""
msgbox, % list.item(1) ; ""

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

Posted: 23 Jun 2017, 05:39
by evilC
I couldn't work out if it was possible, in the end I just returned an array of strings