AutoHotkey.dll and C#

Ask for help, how to use AHK_H, etc.
vbmark
Posts: 36
Joined: 30 Nov 2013, 22:17

AutoHotkey.dll and C#

08 Dec 2013, 09:03

Is there an example C# program that uses the AutoHotkey.dll? I'm trying to figure out how to use some of the AutoHotkey features in my app but can't figure it out.

Also, will the dll be statically linked into my compiled build or will the end user need to install AutoHotkey?

Thanks!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: AutoHotkey.dll and C#

08 Dec 2013, 16:58

Have a look here.

End user will need AutoHotkey.dll, or you use something like MemoryModule (see source code) to load the dll from memory/resources.
vbmark
Posts: 36
Joined: 30 Nov 2013, 22:17

Re: AutoHotkey.dll and C#

08 Dec 2013, 22:12

OK, thanks.
amazingandrew
Posts: 1
Joined: 14 Oct 2014, 15:13

Re: AutoHotkey.dll and C#

14 Oct 2014, 15:17

I needed to use this on a project I was working on. I did a pretty nice wrapper around it and posted it up on github.

https://github.com/amazing-andrew/AutoHotkey.Interop
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: AutoHotkey.dll and C#

15 Oct 2014, 02:11

amazingandrew wrote:I needed to use this on a project I was working on. I did a pretty nice wrapper around it and posted it up on github.

https://github.com/amazing-andrew/AutoHotkey.Interop
well done. this should be linked somewhere

vbmark
Posts: 36
Joined: 30 Nov 2013, 22:17

Re: AutoHotkey.dll and C#

15 Oct 2014, 06:18

amazingandrew wrote:I needed to use this on a project I was working on. I did a pretty nice wrapper around it and posted it up on github.

https://github.com/amazing-andrew/AutoHotkey.Interop
Thank you for sharing this and for making it open source.

I gave it a star in GitHub and I encourage others to do so too.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: AutoHotkey.dll and C#

13 Jun 2017, 18:55

As some of you may be aware, I have been beavering away learning how to implement all kinds of input detection in C# - I have managed to wrap DirectInput, XInput and RawInput into C# DLLs that can be accessed from AHK
The idea is to provide one API that can be loaded from any language that supports CLR (Like AHK) and it provides the ability to subscribe to inputs (eg Joysticks, mice, keyboards, VR controllers, whatever underlying API you want) and drive outputs (Keyboard, mouse, vJoy etc) - all via one standardized set of API calls.

So my next Proof of Concept is to make a C# DLL that loads AutoHotkey.dll and uses it to declare hotkeys and use AHK's Send command etc.

So the flow would be this:
AHK script loads the C# DLL via CLR and passes it a function object (The callback you wish fired when the hotkey is pressed) and some options (eg the hotkey to be bound).
The C# DLL uses AutoHotkey.dll to create the requested hotkey.
Now at this point, I would rather that the C# code was the first thing called when the hotkey fired, so that things like repeat suppression (An option I add to hotkeys to stop the down event repeating when you hold the key) can be done in C#
But whatever, end result should be that when the hotkey is pressed, the autohotkey.dll code fires and ultimately the callback function in the main AHK script gets the event.

Yes, it's a little perverse, ultimately someone using this library for an AHK script would be loading C# from AHK, which would then be spinning up AutoHotkey.dll to provide support for hotkeys, but I do not want to limit this to just working with AHK.

So...
At one point I got a message from someone on one of these projects ?amazingandrew? asking if I wanted to help, but I was too busy with my own stuff.
I tried messing around with this library a while back, but got no joy. Not sure if I was being a doofus or what.

If anyone else is active tinkering in this area, would appreciate any pointers as to how best to proceed.
Gonna give working with this library a try probably this weekend, but I thought it worth at least sending a shout out to see if there was any activity in this area.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: AutoHotkey.dll and C#

14 Jun 2017, 09:07

Well I can create hotkeys, but it is extremely unreliable.

https://github.com/amazing-andrew/AutoH ... p/issues/9
Does anyone have any idea what I am doing wrong? This seems utterly unusable.

Edit: It seems that SendPipeMessage is not reliable when used in a hotkey function
User avatar
Scr1pter
Posts: 1271
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: AutoHotkey.dll and C#

15 May 2019, 11:40

Very interesting!
I had some starting problems, but now I was able to include AHK inside of a C# script.
It is basically some external GUI software, where I assigned a C# script to a button, which uses the AHK library.

The good news: It works!
The bad news: If I click 2 times on a button (I'm not speaking about a double-click),
I always receive the error message: "Error. Duplicate function definition", but the function still gets executed properly (after clicking on OK).

This is the AHK script, which contains the function that I call:

Code: Select all

#Warn All, Off ; Doesn't seem to affect the dialog box

MyFunction(nummer)
{
  if nummer = 1
  {
    SendLevel, 2
    Send {F1}
  }
  if nummer = 2
  {
    SendLevel, 2
    Send {F2}
  }
}
And this is the C# script which is used in an external software:

Code: Select all

using AutoHotkey.Interop;

public class AutoHotKeyTest
{
  public Object button; // Zugriff auf einen Button
  public string nummer; // Button kann eigene Nummer ausführen

  public void Ahk_Test()
  {
    var ahk = AutoHotkeyEngine.Instance; // Grab a copy of the AutoHotkey singleton instance
    ahk.LoadFile("functions.ahk"); // Load a library or exec scripts in a file
    ahk.ExecFunction("MyFunction", nummer); // Execute a specific function (found in functions.ahk), with 1 parameter
  }
}
I assign the numbers (nummer) to buttons directly in the GUI software.

What's the reason for this error?
I've never seen it before anyway.

Cheers!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: AutoHotkey.dll and C#

15 May 2019, 16:17

The problem is that you are loading the same file (functions.ahk) again while the script is still running.
Best is to load your script when creating the instance and only call the functions afterwards.
User avatar
Scr1pter
Posts: 1271
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: AutoHotkey.dll and C#

15 May 2019, 17:18

Thanks for your answer.
Well, it sounds logical, but I must honestly admit I don't know how to write it.

Can you give me an example, please?
burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

Re: AutoHotkey.dll and C#

14 Jul 2019, 15:24

Scr1pter, I would respectfully echo the request for an example, as I'm running into exactly the same trouble with C# macros in G1ANT. If AutoHotkey.Interop had a call for ahkReady(), I think this would be easier in general.
HOWEVER: You might try this (just added 'ahkReset();' as the last call):

Code: Select all

using AutoHotkey.Interop;

public class AutoHotKeyTest
{
  public Object button; // Zugriff auf einen Button
  public string nummer; // Button kann eigene Nummer ausführen

  public void Ahk_Test()
  {
    var ahk = AutoHotkeyEngine.Instance; // Grab a copy of the AutoHotkey singleton instance
    ahk.LoadFile("functions.ahk"); // Load a library or exec scripts in a file
    ahk.ExecFunction("MyFunction", nummer); // Execute a specific function (found in functions.ahk), with 1 parameter
    ahk.Reset();
  }
}
I don't think that 'ahk.Reset()' command is documented on the AutoHotkey.Interop page, but I did find it in the source code. One problem may be solved, but another may crop up. Consider this code, which is not using AutoHotkey.Interop, but AutoHotkey.dll via its COM interface:

Code: Select all

ahkdll := ComObjCreate("AutoHotkey.Script")
ahkdll.ahktextdll("msgbox, Hello")
While ahkdll.ahkReady()
  Sleep, 100
What happens SOMETIMES with C# (and I bet always if you use the COM interface) is that your code will need this ahkReady() call to keep your script from terminating before AHK gets a chance to run.

I'm probably rambling, but take a look at this code that works either with or without the ahk.Reset(). It's scripted and not compiled, taken from a G1ANT script, you'll see sort of what's happening with dlls and namespaces, but that's not really important here. Everything between '⊂⊃' is C#. If you put the delimiters on separate lines it's like an AH continuation section, I suppose).

Code: Select all

addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms
♥hellogiant = "Hello "
⊂
var ahk = AutoHotkeyEngine.Instance;
ahk.ExecRaw("MsgBox, Hello World!");
ahk.SetVar("x", ♥hellogiant);
ahk.SetVar("y", "World, from AHK and G1ANT!");
ahk.ExecRaw("z:=x . y");
string zValue = ahk.GetVar("z");
System.Windows.Forms.MessageBox.Show(zValue);;
ahk.SetVar("z", zValue);
ahk.ExecRaw("Msgbox, I can say %z%");
ahk.Reset();
⊃
It's more or less one of the examples from the AutoHotkey.Interop github page. But then look at this:

Code: Select all

addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll,System.Runtime.InteropServices.dll,System.Reflection.dll,Microsoft.CSharp.dll,System.Threading.Thread.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms,System.Reflection,System.Threading
-text.read C:\G1ANT\ie_com3.ahk result ♥ahkIn

♥ahkIn = ‴C:\G1ANT\ie_com4.ahk‴
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile(♥ahkIn);
MessageBox.Show("Stop thread");
ahk.Reset();
⊃
Without the System.Windows.Forms.MessageBox() call, which stops the thread, the whole C# script bails before the AHK runs. Take it out and see.
@HotKeyIt, could you please suggest a way to provide the same functionality as

Code: Select all

While ahkdll.ahkReady()
  Sleep, 100
but using just AutoHotkey.Interop?

(I'm going to try to add a wrapped call to ahkReady() in a recompiled AutoHotkey.Interop, but frankly, I don't like my chances.)
A million thanks in advance,
burque505
burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

Re: AutoHotkey.dll and C#

14 Jul 2019, 17:01

Well, I'll be hornswoggled - it worked. I was able to add a call to ahkReady() in a recompiled AutoHotkey.Interop. I will try to fork it, but my github skills are nearly non-existent.
This code now works in G1ANT (I will try removing references one-by-one until I don't have so many dependencies, but that's probably immaterial to most people. Unless everybody and his pet duck starts using G1ANT all of a sudden - could happen ;) .

EDIT :) : Forked AutoHotkey.Interop is here.

Code: Select all

addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll,System.Runtime.InteropServices.dll,System.Reflection.dll,Microsoft.CSharp.dll,System.Threading.Thread.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms,System.Reflection,System.Threading
-text.read C:\G1ANT\ie_com3.ahk result ♥ahkIn

♥ahkIn = ‴C:\G1ANT\ie_com4.ahk‴
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
while (ahk.IsReady()==false) {
    Thread.Sleep(100);
}
ahk.LoadFile(♥ahkIn);
//MessageBox.Show("Stop thread");
while (ahk.IsReady()==true) {
    Thread.Sleep(100);
}
ahk.Reset();
⊃
For those (if any) who are interested in this, but can't wait till I get this fork up on github, I just added this code at the end of AutoHotkeyEngine.cs:

Code: Select all

        /// <summary>
        /// Determines whether state is "Ready" or not
        /// </summary>
        /// <param>No parameters</param>
        /// <returns>Returns true if the state is "Ready", otherwise false</returns>
        public bool IsReady()
        {
                    if (AutoHotkeyDll.ahkReady() == true) {
                        return true;
                    }
                    else {
                        return false;
                    }
        }
I believe this would work as well, as this is what Dnspy reports it compiles to anyway:

Code: Select all

        /// <summary>
        /// Determines whether state is "Ready" or not
        /// </summary>
        /// <param>No parameters</param>
        /// <returns>Returns true if the state is "Ready", otherwise false</returns>
public bool IsReady()
{
	return AutoHotkeyDll.ahkReady();
}
        }
Regards,
burque505

Return to “Ask for Help”

Who is online

Users browsing this forum: No registered users and 22 guests