Создать COM из процесса в C#/.Net?

Простую альтернативу этой проблеме можно решить, предоставив соответствующие разрешения в самой базе данных. Например: если вы используете базу данных mysql, введите в базу данных через терминал или предоставленный интерфейс и просто следуйте этой команде:

 GRANT SELECT, INSERT, DELETE ON database TO username@'localhost' IDENTIFIED BY 'password';

Это ограничит пользователя ограничиться только указанным запросом только. Удалите разрешение удаления, и поэтому данные никогда не будут удалены из запроса, запущенного с php-страницы. Второе, что нужно сделать, это очистить привилегии, чтобы mysql обновлял разрешения и обновления.

FLUSH PRIVILEGES; 

Дополнительная информация о flush .

To см. текущие привилегии для пользователя, вызывают следующий запрос.

select * from mysql.user where User='username';

Подробнее о GRANT .

25
задан Community 23 May 2017 в 11:46
поделиться

5 ответов

Одна опция обслуженные компоненты - т.е. разместите ее в COM + как оболочка exe. См. также практическое руководство здесь .

5
ответ дан Marc Gravell 28 November 2019 в 20:58
поделиться

У нас также были некоторые проблемы много лет назад с regasm и выполнением COM-класса как Локальный Сервер EXE.

Это - определенный взлом, и я приветствовал бы любые предложения для создания его более изящным. Это было реализовано для проекта назад в.NET 1,0 дня и не было затронуто с тех пор!

В основном это выполняет regasm стиль регистрации каждый раз, когда приложение запускается (это должно быть выполнено однажды для создания ключей реестра, прежде чем COM-объект инстанцируют в приложении-контейнере COM).

я скопировал следующие важные биты с нашей реализации и переименовал несколько классов для иллюстрирования примера.

следующий метод называют от события Form Loaded для регистрации COM-класса (переименованный к MyCOMClass для этого примера)

private void InitialiseCOM()
    {
        System.Runtime.InteropServices.RegistrationServices services = new System.Runtime.InteropServices.RegistrationServices();
        try
        {
            System.Reflection.Assembly ass = Assembly.GetExecutingAssembly();
            services.RegisterAssembly(ass, System.Runtime.InteropServices.AssemblyRegistrationFlags.SetCodeBase);
            Type t = typeof(MyCOMClass);
            try
            {
                Registry.ClassesRoot.DeleteSubKeyTree("CLSID\\{" + t.GUID.ToString() + "}\\InprocServer32");
            }
            catch(Exception E)
            {
                Log.WriteLine(E.Message);
            }

            System.Guid GUID = t.GUID;
            services.RegisterTypeForComClients(t, ref GUID );
        }
        catch ( Exception e )
        {
            throw new Exception( "Failed to initialise COM Server", e );
        }
    }

Для рассматриваемого типа, MyCOMObject, будет нуждаться в некоторых специальных атрибутах, чтобы быть COM совместимый. Один важный атрибут должен определить фиксированный GUID иначе каждый раз, когда Вы компилируете реестр, заполнится осиротевшими GUID COM. Можно использовать меню Tools в VisualStudio для создания Вас уникальный GUID.

  [GuidAttribute("D26278EA-A7D0-4580-A48F-353D1E455E50"),
  ProgIdAttribute("My PROGID"),
  ComVisible(true),
  Serializable]
  public class MyCOMClass : IAlreadyRegisteredCOMInterface
  {
    public void MyMethod()
    {
    }

    [ComRegisterFunction]
    public static void RegisterFunction(Type t)
    {
      AttributeCollection attributes = TypeDescriptor.GetAttributes(t);
      ProgIdAttribute ProgIdAttr = attributes[typeof(ProgIdAttribute)] as ProgIdAttribute;

      string ProgId = ProgIdAttr != null ? ProgIdAttr.Value : t.FullName;

      GuidAttribute GUIDAttr = attributes[typeof(GuidAttribute)] as GuidAttribute;
      string GUID = "{" + GUIDAttr.Value + "}";

      RegistryKey localServer32 = Registry.ClassesRoot.CreateSubKey(String.Format("CLSID\\{0}\\LocalServer32", GUID));
      localServer32.SetValue(null, t.Module.FullyQualifiedName);

      RegistryKey CLSIDProgID = Registry.ClassesRoot.CreateSubKey(String.Format("CLSID\\{0}\\ProgId", GUID));
      CLSIDProgID.SetValue(null, ProgId);

      RegistryKey ProgIDCLSID = Registry.ClassesRoot.CreateSubKey(String.Format("CLSID\\{0}", ProgId));
      ProgIDCLSID.SetValue(null, GUID);

      //Registry.ClassesRoot.CreateSubKey(String.Format("CLSID\\{0}\\Implemented Categories\\{{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}}", GUID));
      //Registry.ClassesRoot.CreateSubKey(String.Format("CLSID\\{0}\\Implemented Categories\\{{63D5F430-CFE4-11d1-B2C8-0060083BA1FB}}", GUID));
      //Registry.ClassesRoot.CreateSubKey(String.Format("CLSID\\{0}\\Implemented Categories\\{{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}}", GUID));
    }

    [ComUnregisterFunction]
    public static void UnregisterFunction(Type t)
    {
      AttributeCollection attributes = TypeDescriptor.GetAttributes(t);
      ProgIdAttribute ProgIdAttr = attributes[typeof(ProgIdAttribute)] as ProgIdAttribute;

      string ProgId = ProgIdAttr != null ? ProgIdAttr.Value : t.FullName;

      Registry.ClassesRoot.DeleteSubKeyTree("CLSID\\{" + t.GUID + "}");
      Registry.ClassesRoot.DeleteSubKeyTree("CLSID\\" + ProgId);
    }

  }

InitialiseCOM метод в основном использовании формы RegistrationServices для регистрации типа. Платформа тогда использует отражение для нахождения метода отмеченным с эти ComRegisterFunction атрибут и вызывает ту функцию с зарегистрированным типом.

ComRegisterFunction отмеченный метод, рука создает настройки реестра для Локального COM-объекта Сервера EXE, и это может быть по сравнению с regasm, если Вы используете REGEDIT и находите рассматриваемые ключи.

я прокомментировал три \\Registry.ClassesRoot.CreateSubKey вызовы метода, поскольку это было другой причиной, мы должны были зарегистрировать тип сами, поскольку это был OPC-сервер, и сторонние OPC-клиенты используют эти реализованные категории для сканирования для совместимых OPC-серверов. REGASM не включил бы их для нас, если мы не сделали работу сами.

можно легко видеть, как это работает при помещении точек останова на функции, поскольку это запускается.

Наша реализация использовала интерфейс, который был уже зарегистрирован в COM. Для Вашего приложения Вы или должны будете к:-

  1. Расширить регистрационные методы, упомянутые выше, чтобы зарегистрировать интерфейс в COM
  2. Или создать отдельный DLL с интерфейсным определением и затем экспортировать то интерфейсное определение библиотеке типов и регистру, которые, как обсуждено в StackOverflow связывают Вас добавленный в вопросе.
12
ответ дан Rhys 28 November 2019 в 20:58
поделиться

IMO, один из путей, через которые это может быть сделано, должны создать нормальный COM Dll согласно методу, который Вы упомянули в ссылке и затем после регистрации Вашего COM dll, измените его на суррогатный DLL. Это может быть сделано очень легко через утилиту OLEView, хотя можно сделать это вручную также путем изменения ключей реестра также через метод, упомянутый в http://msdn.microsoft.com/en-us/library/ms686606 (По сравнению с 85) .aspx.

Путем создания этого суррогатным DLL, это будет работать в своем собственном dllhost.exe и следовательно будет из процесса.

6
ответ дан Aamir 28 November 2019 в 20:58
поделиться

Вы можете использовать RegistrationServices.RegisterTypeForComClients, который является управляемым эквивалентом CoRegisterClassObject - пример кода см. http://www.andymcm.com/blog/2009/10/managed- dcom-server.html

3
ответ дан 28 November 2019 в 20:58
поделиться

Это можно сделать, используя неуправляемую структуру ATL и подключив ее к управляемому коду. (просто изменив свойства результирующего проекта на / clr).

Вот иллюстративные отрывки:

.H-part:

\#include < vcclr.h >

\#using < MyCSharpModule.dll >

using namespace System;

class ATL_NO_VTABLE MyCSharpProxyServer :
    public CComObjectRootEx< CComMultiThreadModel >,

.....

{

      HRESULT FinalConstruct();

      STDMETHODIMP LoadMyFile(BSTR FileName);
.....
      gcroot<MyCSNamespace::MyCSharpClass^> m_CSClass;

}

.CPP-part:

using namespace System::Collections;

using namespace MyCSNamespace;

HRESULT MyCSharpProxyServer::FinalConstruct()
{

    m_CSClass = gcnew MyCSharpClass();

}

STDMETHODIMP MyCSharpProxyServer::LoadMyFile(BSTR FileName)
{

    try {
       int hr = m_CSClass->LoadFile(gcnew String( FileName));
        return hr;
    }
    catch( Exception^ e )  {
        return E_FAIL;
    }
}

Часть C # (класс MyCSharpClass) находится в отдельном проекте с библиотекой классов выходного типа.

2
ответ дан 28 November 2019 в 20:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: