Новичок
Профиль
Группа: Участник
Сообщений: 3
Регистрация: 27.1.2009
Репутация: нет Всего: нет
|
Здравствуйте. Поломал всю голову поэтому обращаюсь за помощью. Надо написать COM сервер, exe, Out Of Proc. Скажем из клиента С++ доковыряться до методов сервера. Не выходит хоть убейте. Тут Код сервера. | Код | //КЛАСС using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;
namespace Server { [ClassInterface(ClassInterfaceType.None), Guid("BB78D399-0145-426c-8473-A04CCAA36811"), ComVisible(true), ProgId("Program.Server")] public class Server : IServer { public Server() {
} ~Server() {
}
[ComVisible(true)] public static string Guid = "BB78D399-0145-426c-8473-A04CCAA36811"; public int SummTwoNum(int a,int b) { return a + b; } } }
//ИНТЕРФЕЙС using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;
namespace Server { [ComVisible(true), //ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("A50602C0-5BB7-4b51-9534-D479FFBF1CE4")] public interface IServer { int SummTwoNum(int a,int b); } }
//КЛАСС ФАБРИКИ КЛАССОВ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;
namespace Server { [ClassInterface(ClassInterfaceType.None)] [ComVisible(true)] public class ClassFactory : IClassFactoryServer { public int CreateInstance(IntPtr pUnkOuter,ref Guid riid,out IntPtr ppvObject) { ppvObject = IntPtr.Zero; if (pUnkOuter != IntPtr.Zero) { Marshal.ThrowExceptionForHR (ComAPI.CLASS_E_NOAGGREGATION); } if (riid == new Guid(Server.Guid) || riid == new Guid(ComAPI.guidIUnknown)) { ppvObject = Marshal.GetComInterfaceForObject(new Server(), typeof(IServer)); } else { Marshal.ThrowExceptionForHR(ComAPI.E_NOINTERFACE); } return 0; }
public int LockServer(bool lockIt) { return 0; } } }
//ИНТЕРФЕЙС ФАБРИКИ КЛАССОВ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;
namespace Server { [ComVisible(true), //ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid(ComAPI.guidIClassFactory)] public interface IClassFactoryServer { [PreserveSig] int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject); [PreserveSig] int LockServer(bool fLock); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Win32; using System.Runtime.InteropServices;
namespace Server { [ComVisible(true)] public class ComAPI { [DllImport("OLE32.DLL")] public static extern UInt32 CoInitializeSecurity ( IntPtr securityDescriptor, Int32 cAuth, IntPtr asAuthSvc, IntPtr reserved, UInt32 AuthLevel, UInt32 ImpLevel, IntPtr pAuthList, UInt32 Capabilities, IntPtr reserved3 );
[DllImport("ole32.dll")] public static extern UInt32 CoRegisterClassObject( ref Guid rclsid, [MarshalAs(UnmanagedType.Interface)]IClassFactoryServer pUnkn, int dwClsContext, int flags, out int lpdwRegister); [DllImport("ole32.dll")] public static extern UInt32 CoRevokeClassObject(int dwRegister); 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); public const string guidIClassFactory = "00000001-0000-0000-C000-000000000046"; public const string guidIUnknown = "00000000-0000-0000-C000-000000000046"; } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;
namespace Server { [ComVisible(true)] public partial class Program { [STAThread] static void Main(string[] args) { OnStart(); Console.Read(); } private static int _cookie = 0; private static void OnStart() { Guid CLSID_MyObject = new Guid(Server.Guid); UInt32 hResult = ComAPI.CoRegisterClassObject( ref CLSID_MyObject, new ClassFactory(), ComAPI.CLSCTX_LOCAL_SERVER, ComAPI.REGCLS_MULTIPLEUSE, out _cookie); if (hResult != 0) throw new ApplicationException( "CoRegisterClassObject failed" + hResult.ToString("X")); else Console.WriteLine("CoRegisterClassObject successfully!"); } private static void OnStop() { if (_cookie != 0) ComAPI.CoRevokeClassObject(_cookie); } } }
|
Сгенерил .Tlb , использовал его в клиенте... Сервер регистрировал всячески, как только можно и нельзя. Результат один. В клиенте так и не получил желаемого результата. Вот клиент простенький на С++ | Код | // COMClient.cpp : Defines the entry point for the console application. //
#include "stdafx.h" #import "D:\Work\COM.EXE\TEST\COMClient\COMClient\COMClient\Debug\Server.tlb" #import "D:\Work\COM.EXE\TEST\COMClient\COMClient\COMClient\Debug\OPCServer.tlb" #import "D:\Work\COM.EXE\TEST\Server\Server\WINServerCOMCSharp\bin\Debug\WINServerCOMCSharp.tlb"
template <class SmartPtrClass> bool CreateInstance(LPCTSTR lpszProgID, SmartPtrClass& spSmartPtrReceiver, DWORD dwClsContext = CLSCTX_ALL) { HRESULT hrRetTemp = S_OK; _bstr_t bstProgID(lpszProgID); CLSID clsid; bool bRet = false; hrRetTemp = CLSIDFromProgID ( (LPCOLESTR)bstProgID, //Pointer to the ProgID (LPCLSID)&clsid //Pointer to the CLSID ); if (hrRetTemp == S_OK) { if (SUCCEEDED(spSmartPtrReceiver.CreateInstance(clsid, NULL, dwClsContext))) { bRet = true; } else { bRet = false; } }
return bRet; }
// Generic CreateInstanceByClassFactory() templated function to help in // generic object creation. The class factory of the coclass is used to // create the instance. template <class SmartPtrClass> bool CreateInstanceByClassFactory ( LPCTSTR lpszProgID, SmartPtrClass& spSmartPtrReceiver, IClassFactoryPtr spIClassFactoryPtrReceiver, DWORD dwClsContext = CLSCTX_ALL ) { HRESULT hrRetTemp = S_OK; _bstr_t bstProgID(lpszProgID); CLSID clsid; bool bRet = false; hrRetTemp = CLSIDFromProgID ( (LPCOLESTR)bstProgID, //Pointer to the ProgID (LPCLSID)&clsid //Pointer to the CLSID );
if (hrRetTemp == S_OK) { CoGetClassObject ( (REFCLSID)clsid, //CLSID associated with the class object (DWORD)dwClsContext, //Context for running executable code (COSERVERINFO*)NULL, //Pointer to machine on which the object is to be instantiated (REFIID)IID_IClassFactory, //Reference to the identifier of the interface (LPVOID *)&spIClassFactoryPtrReceiver //Address of output variable that receives the // interface pointer requested in riid ); } if (spIClassFactoryPtrReceiver) { hrRetTemp = spIClassFactoryPtrReceiver -> CreateInstance ( NULL, __uuidof(SmartPtrClass), (LPVOID *)&spSmartPtrReceiver ); if (SUCCEEDED(hrRetTemp)) { bRet = true; } else { bRet = false; } }
return bRet; }
long e = 2; long w = 5;
int _tmain(int argc, _TCHAR* argv[]) { ::CoInitialize(NULL); if (1) { // ISimpleCOMObjectPtr is a smart pointer class which will manage // a pointer to the COM interface ISimpleCOMObject for us. //COMLIB::ICOMLPtr spISimpleCOMObject1;// = NULL; //COMLIB::ICOMLPtr spISimpleCOMObject2;// = NULL; //PROCOUTSERVER::ICLASSFACROTYPtr spIClassFactory;// = NULL;
Server::IServerPtr spISimpleCOMObject1;// = NULL; Server::IServerPtr spISimpleCOMObject2;// = NULL; Server::IClassFactoryServerPtr spIClassFactory;// = NULL; //WINServerCOMCSharp::IServerPtr qwe1;// = NULL; //WINServerCOMCSharp::IServerPtr qwe2 ;//= NULL; //WINServerCOMCSharp::IClassFactoryServerPtr werwer;
// We create an instance of the class factory of the coclass // whose CLSID is synonymous with the ProgID // "ManagedCOMLocalServer_Impl01.SimpleCOMObject". // From this class factory object, we will also create an // instance of the above-mentioned coclass and get hold of // its ISimpleCOMObject interface.
CreateInstanceByClassFactory<Server::IServerPtr> ( (LPCTSTR)"Program.Server", spISimpleCOMObject1, spIClassFactory, CLSCTX_LOCAL_SERVER );
if (spIClassFactory) { spIClassFactory -> LockServer(TRUE); }
if (spISimpleCOMObject1) { e = spISimpleCOMObject1 ->SummTwoNum(2,2); //spISimpleCOMObject1 -> Method01(_bstr_t("C# EXE Local Server. The Long Property Value Is : ")); // Next Release() spISimpleCOMObject1. spISimpleCOMObject1 = NULL; }
// We create an instance of an implementation of the ISimpleCOMObject interface // as provided by the COM class whose CLSID is synonymous // with the ProgID "ManagedCOMLocalServer_Impl01.SimpleCOMObject". CreateInstance<Server::IServerPtr> ( (LPCTSTR)"Program.Server", spISimpleCOMObject2, /*CLSCTX_INPROC_SERVER*/ CLSCTX_LOCAL_SERVER ); if (spISimpleCOMObject2) { w = spISimpleCOMObject2 ->SummTwoNum(3,3); //spISimpleCOMObject2 -> Method01(_bstr_t("C# EXE Local Server. The Long Property Value Is : ")); spISimpleCOMObject2 = NULL; } if (spIClassFactory) { spIClassFactory -> LockServer(FALSE); spIClassFactory = NULL; } }
printf("spISimpleCOMObject1 - %d", e); printf("\n"); printf("spIClassFactory - %d", w); getchar(); ::CoUninitialize();
return 0; }
З.Ы. Мучаюсь уже неделю... Надеюсь на помощь...
|
|