G1ANT-在C#宏中处理非托管代码

时间:2019-07-12 15:44:07

标签: c# g1ant

我很喜欢使用G1ANT的“宏”功能来调用非托管代码,但是非托管对象当然不会被自动垃圾回收而缺少代码来做到这一点。

我的请求专门针对在这些G1ANT C#宏中处理非托管代码的最佳实践,不是,通常是在C#中处理相同代码的请求,不是请求修复下面的代码,该代码可以正常运行。

如果我使用Visual Studio在C#中进行编码,则可能会使用System.Runtime.InteropServices.SafeHandle类,覆盖Finalize方法或使用其他常用方法之一(另请参见this post on disposing of unmanaged objects in C# )。

但是,至少从我的新手经验来看,这些方法似乎都不适合G1ANT宏

出于说明目的,我指的是此G1ANT代码,但没有宏(ahk.Reset())的最后一行,因为它在该行上运行良好,不止一次。 (我很痛苦地意识到,必须有一个更好的示例,但是由于我是G1ANT的新手,所以到目前为止,这是我唯一的一件事。)我所追求的是在< strong>是没有明确处理非托管对象:

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
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile("functions.ahk");

//execute a specific function (found in functions.ahk), with 2 parameters
ahk.ExecFunction("MyFunction", "Hello", "World");

string sayHelloFunction = "SayHello(name) \r\n { \r\n MsgBox, Hello %name% \r\n return \r\n }";
ahk.ExecRaw(sayHelloFunction);

//execute's newly made function\
ahk.ExecRaw(@"SayHello(""Mario"") ");

var add5Results = ahk.ExecFunction("Add5", "5");
MessageBox.Show("ExecFunction: Result of 5 with Add5 func is" + add5Results);
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
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms,System.Reflection
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile("functions.ahk");

//execute a specific function (found in functions.ahk), with 2 parameters
ahk.ExecFunction("MyFunction", "Hello", "World");

string sayHelloFunction = "SayHello(name) \r\n { \r\n MsgBox, Hello %name% \r\n return \r\n }";
ahk.ExecRaw(sayHelloFunction);

//executes new function
ahk.ExecRaw(@"SayHello(""Mario"") ");

var add5Results = ahk.ExecFunction("Add5", "5");
MessageBox.Show("ExecFunction: Result of 5 with Add5 func is" + add5Results);
ahk.Reset();
⊃
⊃

它几乎是the AutoHotkey.Interop github page.上的全部文字

在宏的最后一行('ahk.Reset())中,代码在第一次运行时运行完美,但是在第二次运行中,G1ANT仍然可以看到包含的AutoHotkey文件,并警告重复的函数定义,但仍会继续并且仍然可以正常运行。据我所知,未公开的AutoHotkey.Interop命令Reset()通过调用来解决垃圾收集问题

        public void Terminate()
        {
                AutoHotkeyDll.ahkTerminate(1000);
        }

        public void Reset() {
                Terminate();
                AutoHotkeyDll.ahkReload();
                AutoHotkeyDll.ahktextdll("", "", "");
        }

因此,即使没有ahk.Reset();,AutoHotkeyEngine实例本身也似乎是垃圾回收的,但它加载到对象中的AutoHotkey脚本却不是。

停止G1ANT.Robot应用程序并重新启动,然后重新加载(如前所述,没有行ahk.Reset();上的脚本,效果很好,但再次只能运行一次。

编辑:从现在开始,在加载AutoHotkey函数脚本和DLL本身时,将使用给定答案的有关单例处理的建议。检查是否已加载DLL或功能文件,是否存在问题,这似乎是一种明智和好的做法。此外,我还分叉了AutoHotkey.Interop存储库here,添加了布尔检查以查看AutoHotkeyEngine实例是否准备就绪。

最诚挚的问候,

burque505

1 个答案:

答案 0 :(得分:2)

您使用AutoHotkeyEngine.Instance,所以我想这是一个单例。只要相应的dll保留在内存中,它就会一直保持在内存中,而只要应用程序域存在,就将加载后者。应用程序域在机器人和脚本之间共享,因此您的单例实例与机器人一样存在。 要么:

  • 不要使用单例,
  • 或在获取实例后立即将其重置(请确定您已经做过的事情)
  • 或将其视为寿命比您的应用程序更长的单例。在这种情况下,获取单例实例后,请检查您的函数文件是否已经加载,并且仅在尚未完成的情况下加载它。