Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> COM (.exe) Сервер на C#, Нужна всякая помощь по этой теме 
:(
    Опции темы
Pauk1
Дата 20.3.2009, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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;
}





З.Ы. Мучаюсь уже неделю... Надеюсь на помощь...


PM MAIL   Вверх
arilou
Дата 20.3.2009, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 3
Всего: 61



Цитата

  [ComVisible(true)] 
        public static string Guid = "BB78D399-0145-426c-8473-A04CCAA36811";
        public int SummTwoNum(int a,int b)
        {
            return a + b;
        }


у тебя ComVisible стоит над статическим полем, а не методом класса.


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Pauk1
Дата 20.3.2009, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 27.1.2009

Репутация: нет
Всего: нет



Так все равно весь интерфейс комвизибл тру.

    ComVisible(true),
    ProgId("Program.Server")]
    public class Server : IServer

но дело в том что до Методов то и не доходит. Даже ссылка на интерфейс не получается. Вот в чем дело...


ЗЫ Просто на самом деле было бы очень хорошо чтобы хоть на одном форуме висела хоть какая то полезная попытка создать Out-Of-Proc COM сервер. А то нигде нету примера или хотябы мануала по тому как сделать exe Com сервер на C#. только куски из которых рабочего проекта не собирается

Это сообщение отредактировал(а) Pauk1 - 20.3.2009, 16:01
PM MAIL   Вверх
PashaPash
Дата 20.3.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 6
Всего: 49



Pauk1, посмотри в MSDN класс System.EnterpriseServices.ServicedComponent и ActivationOption Enumeration.
Или пример с http://www.codeproject.com/KB/COM/BuildCOM...rsInDotNet.aspx


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, cully, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Распределённые приложения и сеть | Следующая тема »


 




[ Время генерации скрипта: 0.0457 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.