天天看点

C#中使用NRegFreeCom动态加载AutoIt3DLL

NRegFreeCom项目地址:

https://github.com/OpenSharp/NRegFreeCom

项目介绍:

Load native libraries, call native functions, do COM objects without registration, do COM registrations in runtime, in .NET

COM is good for native interop and easy IPC, but lacks clean coded way to do such interaction without deployment/compile time registry in .NET.

Managed code is XCOPY on 32/64. This lib helps making native interlop also XCOPY by using pattern of deploying both versions of native libs and deciding in runtime, like OS libraries PInvokes work.

This project contains samples and reusable patters of things above.

大概意思就是不用注册来调用COM中的功能

以下示例调用AutoIt3的功能:

助手,返回AutoItX3接口对象

class AutoItHelper
    {
        public IAutoItX3 getAutoIt()
        {
            var bin = Path.GetFullPath(".");
            var dlls = new NRegFreeCom.AssemblySystem();
            dlls.AddSearchPath(bin);
            var dll = dlls.LoadFrom(Path.Combine(bin, "AutoItX3.dll"));
            return new AutoItX3Lib.AutoItX3();
        }
    }
           

如果是32/64位的程序用以下代码确定路径:

var loader = new AssemblySystem();

        // C# loads C++ from Win32 or x64 subfolder
        var anyCpu = loader.GetAnyCpuPath(loader.BaseDirectory);      

测试调用记事本:

string notepad = "c:\\windows\\notepad.exe";

            AutoItHelper helper = new AutoItHelper();
            var au = helper.getAutoIt();
            au.Run(notepad, "", 1);
            au.WinWaitActive("无标题");
            au.Send(string.Format("现在是:{0}", DateTime.Now));
           

除了上面的方法,还可以用以下方法来调用:

var createdViaManifest = NRegFreeCom.ActivationContext.CreateInstanceWithManifest(new Guid("{1A671297-FA74-4422-80FA-6C5D8CE4DE04}"), "AutoItX3Dependency.manifest");
            var au = (IAutoItX3)createdViaManifest;
            au.Run(notepad, "", 1);
            au.WinWaitActive("无标题");
            au.Send("abc");
            Console.ReadKey();
           

这时需要两个配置文件:AutoItX3.dll.manifest和AutoItX3Dependency.manifest

内容分别为:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="AutoItX3.dll" version="3.3.8.1" />
  <file name = "AutoItX3.dll">
    <comClass
        clsid="{1A671297-FA74-4422-80FA-6C5D8CE4DE04}"
        threadingModel = "Free" />
    <typelib tlbid="{F8937E53-D444-4E71-9725-35B64210CC3B}"
          version="1.0" helpdir=""/>
  </file>
  <comInterfaceExternalProxyStub
      name="IAutoItX3"
      iid="{3D54C6B8-D283-40E0-8FAB-C97F05947EE8}"
    proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
    baseInter
      tlbid = "{F8937E53-D444-4E71-9275-35B64210CC3B}" />
</assembly>
           

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <dependency>
    <dependentAssembly  asmv2:codebase="AutoItX3.dll.manifest">
      <assemblyIdentity name="AutoItX3.dll" version="3.3.8.1" type="win32" />
    </dependentAssembly>
  </dependency>
</asmv1:assembly>
           

使用这种方法调用的好处是不用写包裹文件,调用的函数名称也和原来的一致,调用起来更简单。