網(wǎng)上有些進(jìn)程外的一些資料,但有些簡(jiǎn)單,研究了兩天寫(xiě)了demo,可利用這種方式解決64位的程序調用32位的dll等問(wèn)題,但注意方法參數不能含有IntPtr,因為指針跨進(jìn)程是無(wú)效的,每個(gè)進(jìn)程都有自己的內存區域

編寫(xiě)com接口,guid可利用vs的工具生成,代碼設置com接口的可視,實(shí)現接口后,編寫(xiě)com工廠(chǎng)啟用com

- internal static class ComHelperClass
- {
- public const string s_IID_ITestComVisible = "C66C0654-49AE-4f2e-8EDA-BD01C8259C20";
- public const string s_CLSID_TestComVisibleClass = "12D783BB-33BF-4973-B38B-2A8F0BA926E4";
- public static readonly Guid IID_ITestComVisible = new Guid(s_IID_ITestComVisible);
- public static readonly Guid CLSID_TestComVisibleClass = new Guid(s_CLSID_TestComVisibleClass);
- public const string s_IID_IClassFactory = "00000001-0000-0000-C000-000000000046";
- public static readonly Guid IID_IClassFactory = new Guid("00000001-0000-0000-C000-000000000046");
- public static readonly Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
- [DllImport("ole32.dll")]
- public static extern int CoRegisterClassObject(
- [MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
- [MarshalAs(UnmanagedType.IUnknown)] object pUnk,
- uint dwClsContext,
- uint flags,
- out uint lpdwRegister);
- [DllImport("ole32.dll")]
- public static extern int CoRevokeClassObject(uint dwRegister);
- [DllImport("ole32.dll")]
- public static extern int CoInitializeSecurity(
- IntPtr securityDescriptor,
- Int32 cAuth,
- IntPtr asAuthSvc,
- IntPtr reserved,
- UInt32 AuthLevel,
- UInt32 ImpLevel,
- IntPtr pAuthList,
- UInt32 Capabilities,
- IntPtr reserved3);
- public const int RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6; // Encrypted DCOM communication
- public const int RPC_C_IMP_LEVEL_IDENTIFY = 2; // No impersonation really required
- public const int CLSCTX_LOCAL_SERVER = 4;
- public const int REGCLS_MULTIPLEUSE = 1;
- public const int EOAC_DISABLE_AAA = 0x1000; // Disable Activate-as-activator
- public const int EOAC_NO_CUSTOM_MARSHAL = 0x2000; // Disable custom marshalling
- public const int EOAC_SECURE_REFS = 0x2; // Enable secure DCOM references
- public const int CLASS_E_NOAGGREGATION = unchecked((int)0x80040110);
- public const int E_NOINTERFACE = unchecked((int)0x80004002);
- }
- [ComVisible(true)]
- [Guid(ComHelperClass.s_IID_ITestComVisible)]
- public interface ITestComVisible
- {
- [DispId(1)]
- string TestProperty { get; set; }
- [DispId(2)]
- void TestMethod();
- //可擴展相應的方法接口,并在TestComVisibleClass 實(shí)現
- }
- [ComVisible(true)]
- [Guid(ComHelperClass.s_CLSID_TestComVisibleClass)]
- public class TestComVisibleClass : ITestComVisible
- {
- public string TestProperty { get; set; }
- public void TestMethod()
- {
- MessageBox.Show("我是32");
- }
- }
- // 類(lèi)廠(chǎng)
- [
- ComImport,
- InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
- Guid(ComHelperClass.s_IID_IClassFactory)
- ]
- internal interface IClassFactory
- {
- [PreserveSig]
- int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
- [PreserveSig]
- int LockServer(bool fLock);
- }
- internal class ComClassFactory : IClassFactory
- {
- #region IClassFactory Members
- public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
- {
- ppvObject = IntPtr.Zero;
- if (pUnkOuter != IntPtr.Zero)
- Marshal.ThrowExceptionForHR(ComHelperClass.CLASS_E_NOAGGREGATION);
- if (riid == ComHelperClass.IID_ITestComVisible ||
- riid == ComHelperClass.IID_IUnknown)
- {
- ppvObject = Marshal.GetComInterfaceForObject(
- new TestComVisibleClass(), typeof(ITestComVisible));
- }
- else
- Marshal.ThrowExceptionForHR(ComHelperClass.E_NOINTERFACE);
- return 0; // S_OK
- }
- public int LockServer(bool fLock)
- {
- return 0; // S_OK
- }
- #endregion
- }
- static void Main()
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- RegisterDcomServer();
- Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
- Application.Run(new Form1());
- }
- static void Application_ApplicationExit(object sender, EventArgs e)
- {
- RevokeDcomServer();
- }
- private static void RegisterDcomServer()
- {
- // 做一些安全檢查,確保只有一些有權限的人才能調用你的C# Dcom組件
- // 如果你對安全性不關(guān)心的話(huà),可以刪除下面的語(yǔ)句
- //int hr = ComHelperClass.CoInitializeSecurity(
- // IntPtr.Zero, // 這里要輸入你的安全描述符
- // -1,
- // IntPtr.Zero,
- // IntPtr.Zero,
- // ComHelperClass.RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
- // ComHelperClass.RPC_C_IMP_LEVEL_IDENTIFY,
- // IntPtr.Zero,
- // ComHelperClass.EOAC_DISABLE_AAA | ComHelperClass.EOAC_SECURE_REFS | ComHelperClass.EOAC_NO_CUSTOM_MARSHAL,
- // IntPtr.Zero);
- //if (hr != 0)
- // Marshal.ThrowExceptionForHR(hr);
- int hr = ComHelperClass.CoRegisterClassObject(
- ComHelperClass.CLSID_TestComVisibleClass,
- new ComClassFactory(),
- ComHelperClass.CLSCTX_LOCAL_SERVER,
- ComHelperClass.REGCLS_MULTIPLEUSE,
- out m_ComCookie);
- if (hr != 0)
- Marshal.ThrowExceptionForHR(hr);
- }
- private static void RevokeDcomServer()
- {
- if (m_ComCookie != 0)
- ComHelperClass.CoRevokeClassObject(m_ComCookie);
- }


查看系統注冊表(建議使用RegWorkshop查看,檢索guid )


vs使用的話(huà)到此就可以了,但如果c++調用的話(huà)還要在注冊表里聲明下tlb的信息
tlb信息可以用oleview進(jìn)行查看,并在注冊表添加信息


新建一個(gè)winform程序 ,編寫(xiě)調用代碼,即可
- System.Type t = Type.GetTypeFromProgID("TestComServer.TestComVisibleClass");
- dynamic o = Activator.CreateInstance(t);
- o.TestMethod();
至此我們的進(jìn)程外com服務(wù)的編寫(xiě)和測試程序全部完成
注意下載Demo后,要現在本地進(jìn)行com注冊和相應注冊表修改,如果感覺(jué)注冊表操作麻煩,可以自己寫(xiě)個(gè)腳本
參考資料:
http://blog.csdn.net/zxdu721/article/details/7785277
https://www.cnblogs.com/killmyday/articles/1395432.html
https://www.codeproject.com/KB/COM/simplecomserver.aspx?display=Print
聯(lián)系客服