2015-01-29 6 views
1

В: Могу ли я сделать собственный клиент, который потребляет компонент .NET COM, используя reg free COM?Может ли собственное приложение использовать без регистрации COM для использования компонента .NET COM?

I.e. Могу ли я сделать приложение C++ с информацией COM в своем манифесте, вместо того, чтобы регистрировать компонент (COM 'stuff') в реестре?


Примечание: Я начал смотреть на Изотермах свободного COM с этим вопросом в виде, и не нашел быстрый ответ через веб-поиск. Когда я нашел ответ, подумал, что я бы разместил на SO в случае, если кто-то еще ищет ...

+0

Простой способ сделать это: http://stackoverflow.com/a/23073183/1768303 – Noseratio

ответ

2

Да.

И вот MSDN есть статья (с 2005), который идет через рабочий пример:

... регистрация свободной активации компонента .NET Framework на основе нативным клиентами через COM Interop. (11 печатных страниц)
https://msdn.microsoft.com/en-us/library/ms973915.aspx(доступ к Jan 2015)

+0

С одной стороны, это это довольно полезный пост в блоге. С другой стороны, когда эта связь нарушает этот ответ, это будет бесполезно бесполезным. Не могли бы вы хотя бы суммировать его здесь, прежде чем связываться с полным прохождением? – Shog9

+0

Хм. Хороший момент о том, когда связь умирает, но сложная, поскольку я отметил «11 печатных страниц»:) Я посмотрю, что я могу сделать – Daryn

2

Дарын,

Эта запись в блоге объяснить вам, как это сделать: http://blogs.msdn.com/b/rodneyviana/archive/2015/08/24/pure-native-c-consuming-net-classes-without-com-registration.aspx

В основном вы используете точку входа верните указатель на интерфейс (используя DllExport Nuget для «экспорта»):

using System; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using RGiesecke.DllExport; 

namespace ContosoCom 
{ 

public static class Exports 
{ 
    [DllExport(CallingConvention = CallingConvention.Cdecl)] 
    public static void GetClass([Out] [MarshalAs((UnmanagedType.Interface))] out IMyClass pInterface) 
    { 
     pInterface = new MyClass(); 
    } 
} 


[ComVisible(true)] 
[System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)] 
public interface IMyClass 
{ 
    void DisplayMessageBox([MarshalAs(UnmanagedType.BStr)] string Text); 
    void GetTicksAndDate([Out] out MyStruct Structure); 
} 

[ComVisible(true)] 
[StructLayout(LayoutKind.Sequential, Pack = 8)] 
public struct MyStruct 
{ 
    public long TicksOfNow; 
    public int Day; 
    public int Month; 
    public int Year; 
} 

[ComVisible(true)] 
[ClassInterface(ClassInterfaceType.None)] 
[ComDefaultInterface(typeof(IMyClass))] 
public class MyClass : IMyClass 
{ 

    public void DisplayMessageBox(string Text) 
    { 
     MessageBox.Show(Text); 
    } 

    public void GetTicksAndDate(out MyStruct Structure) 
    { 
     Structure.TicksOfNow = DateTime.Now.Ticks; 
     Structure.Day = DateTime.Now.Day; 
     Structure.Month = DateTime.Now.Month; 
     Structure.Year = DateTime.Now.Year; 
    } 
} 

}

И это как код C++ выглядит следующим образом:

#include "stdafx.h" 
#import "..\..\bin\Debug\ContosoCom.tlb" auto_rename 


using namespace ContosoCom; 
typedef void(*pGetClass)(IMyClass **iMyClass); 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
pGetClass getClass = NULL; 
IMyClass *mc = NULL; 

HINSTANCE hDLL = 0; 
// load the DLL 

hDLL = ::LoadLibrary(L"ContosoCom.dll"); 

::CoInitialize(NULL); 

if(!hDLL) 
{ 
    printf("ERROR: Unable to load library ContosoCom.dll\n"); 
    return -1; 
} 


// 
// TO DO: Add code here to get an instance of MyClass 
// 
getClass = (pGetClass)GetProcAddress(hDLL, "GetClass"); 

if(!getClass) 
{ 
    printf("ERROR: Unable to find entry for GetClass()\n"); 
    return -1; 

} 

getClass(&mc); 

// At this point we do not have how to get a pointer even with the libray loaded 

// End of TO DO 

if(!mc) 
{ 
    printf("ERROR: Unable to get a pointer for MyClass\n"); 
    return -1; 
} 

mc->DisplayMessageBox("Hello World from native to .NET without registration"); 
MyStruct st; 
ZeroMemory(&st, sizeof(MyStruct)); 
mc->GetTicksAndDate(&st); 
printf("Ticks %I64i\n",st.TicksOfNow); 
printf("Today is %i/%i/%i\n",st.Month,st.Day,st.Year); 


printf("SUCCESS: Leaving gracefully\n"); 
return 0; 
}