NPAPI plugin not detected by Firefox - visual-studio-2010

I'm trying to make Firefox (16.0.2 under Windows 7 x64 Professional) detect a blank NPAPI plugin. Here's my code.
nplithium.def
LIBRARY nplithium
EXPORTS
NP_GetEntryPoints #1
NP_Initialize #2
NP_Shutdown #3
nplithium.rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Antek SRL"
VALUE "FileDescription", "Example Lithium"
VALUE "FileVersion", "1.0.0.2"
VALUE "InternalName", "nplithium"
VALUE "LegalCopyright", "Copyright (C) Marco Buzzanca 2012"
VALUE "MIMEType", "application/x-lithium"
VALUE "OriginalFilename", "nplithium.dll"
VALUE "ProductName", "lithium"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
dll_entry.cpp
#include "npapi.h"
#include "npfunctions.h"
extern "C"
{
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* functions)
{
if(functions == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if(functions->size < sizeof(NPPluginFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
functions->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
functions->newp = NULL;
functions->destroy = NULL;
functions->setwindow = NULL;
functions->newstream = NULL;
functions->destroystream = NULL;
functions->asfile = NULL;
functions->writeready = NULL;
functions->write = NULL;
functions->print = NULL;
functions->event = NULL;
functions->urlnotify = NULL;
functions->getvalue = NULL;
functions->setvalue = NULL;
functions->javaClass = NULL;
return NPERR_NO_ERROR;
}
NPError OSCALL NP_Initialize(NPNetscapeFuncs* functions)
{
return NPERR_NO_ERROR;
}
NPError OSCALL NP_Shutdown()
{
return NPERR_NO_ERROR;
}
}
Unfortunately, all of the sample plugins and tutorials I've found on the web are either obsolete or incomplete. The MDN doesn't help either, as it provides little to no information about what the browser expects these functions to do (NP_GetEntryPoints is completely undocumented).
Is there something I'm missing? I am not trying to make the plugin do anything, I just want firefox to detect it.

I managed to make Firefox detect my plugin.
As specified in plug-in developement overview:
For this the version stamp of the embedded resource of the plug-in DLL
should contain the following set of string/value pairs:
MIMEType: for MIME types
FileExtents: for file extensions
FileOpenName: for file open template
ProductName: for plug-in name
FileDescription: for description
Language: for language in use
I was missing a few of these pairs in my .rc file.

Related

Dock/Anchor alternative in C++ for List Control

In .NET there are Anchor & Dock properties that can make the controls responsive whenever you resize the window.
I want to do something similar with this C++ List Control. Basically I want to dock it in the dialog, so when I resize the window, it should be resizing.
#include <Windows.h>
#include "resource.h"
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#include <CommCtrl.h> // LV_COLUMN and ListView_x
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
wchar_t c0_txt[] = L"Dogzu";
switch (Message)
{
case WM_INITDIALOG:
LVCOLUMNW col;
col.mask = LVCF_TEXT | LVCF_WIDTH | LVIF_IMAGE;
col.cx = 60;
col.pszText = c0_txt;
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LIST1), 0, &col);
return TRUE;
case WM_NCDESTROY:
PostQuitMessage(0);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
DestroyWindow(hWnd);
break;
default:
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HWND hWnd = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, &DialogProc, 0);
if (!hWnd)
{
MessageBoxW(nullptr, L"Dialog Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageW(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 302
TOPMARGIN, 7
BOTTOMMARGIN, 169
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Test"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,21,25,268,123
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_MAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
There is no docking support in the Windows API. You'll have to implement it manually by handling the WM_SIZE message:
case WM_SIZE: {
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
// IDC_LIST1 will occupy the entire client area of its parent.
// Adjust as needed.
MoveWindow(GetDlgItem(hWnd, IDC_LIST1),
0, 0, width, height, TRUE);
return TRUE;
}

Doxygen+Sphinx+Breathe+Exhale

Currently, I am working on project documentation. When I include source file and header file in conf.py the HTML generated successfully. But when I want to use source file only to documentation HTML file, there has something wrong on it. Such as following,
My conf.py content as below,
# Setup the exhale extension
exhale_args = {
# These arguments are required
"containmentFolder": "./api",
"rootFileName": "library_root.rst",
"rootFileTitle": "Library API",
"doxygenStripFromPath": "..",
# Suggested optional arguments
"createTreeView": True,
# TIP: if using the sphinx-bootstrap-theme, you need
# "treeViewIsBootstrap": True,
"exhaleExecutesDoxygen": True,
"exhaleDoxygenStdin": textwrap.dedent('''
EXTRACT_ALL = YES
SOURCE_BROWSER = YES
EXTRACT_STATIC = YES
OPTIMIZE_OUTPUT_FOR_C = YES
HIDE_SCOPE_NAMES = YES
QUIET = YES
INPUT = ../include ../src
FILE_PATTERNS = *.c *.h
EXAMPLE_RECURSIVE = YES
GENERATE_TREEVIEW = YES
''')
}
The source file and header file with success result
[Source File]
/**
* #brief Fills the data buffer
* #param[in] Data buffer
* #return pointer to the data buffer
**/
char* at_test_action(void* data)
{
char* ptr = (char*) data;
sprintf( ptr, "AT\r\n" );
return ptr;
}
[Header File]
#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C" {
#endif
char* at_test_action(void* data);
#ifdef __cplusplus
}
#endif
#endif /* TEST_H */
The source file and header file with fail result
[Source File]
/**
* #brief Fills the data buffer
* #param[in] Data buffer
* #return pointer to the data buffer
**/
char* at_test_action(void* data)
{
char* ptr = (char*) data;
sprintf( ptr, "AT\r\n" );
return ptr;
}
[Header File]
#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C" {
#endif
// char* at_test_action(void* data);
#ifdef __cplusplus
}
#endif
#endif /* TEST_H */
And I can use Doxygen without header file to generate result which I want.
Thank you very much.
2020.01.31 Update (UTC Time: 02:51)
Because of duplicate documentation, I want to add below comment into header file.
http://doxygen.10944.n7.nabble.com/Remove-detailed-documentation-from-header-td3679.html
#cond INCLUDE_THIS_SECTION_IN_DOXYGEN_OUTPUT
/* #endcond */
[Header File]
#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C" {
#endif
/* #cond INCLUDE_THIS_SECTION_IN_DOXYGEN_OUTPUT */
char* at_test_action(void* data);
/* #endcond */
#ifdef __cplusplus
}
#endif
#endif /* TEST_H */
[Source File]
/**
* \brief Fills the data buffer
* \param[in] data data buffer for content preparation
* \return pointer to the data buffer
**/
char* at_test_action(void* data)
{
char* ptr = (char*) data;
sprintf( ptr, "AT\r\n" );
return ptr;
}
Without above #cond the Doxygen result as following. Actually, in Doxygen representation is good for me.
But when change to Sphinx representation, user will see two same functions and list at sidebar without any detail information to distinguish it:
I am new for those tools, if there has stupid questions or the information is not enough, please let me know. Thank you very much.
One problem is the incorrect usage of the #param statement with doxygen. The syntax is \param '['dir']' <parameter-name> { parameter description }.
In your example the parameter name would be Data whilst the parameter in fact is data. As far as I can guess your intended use is #param[in] data Data buffer.

Error C2491: Function declared in header and defined in C++

I have been trying to build a device adapter for a open-source software called Micro-manager to control a microscope and there are some problems that I am facing, there are these two files (one header and the other CPP) that are already present in the open source package of Micro-Manager.
//MoudluleInterface.h
#ifndef _MODULE_INTERFACE_H_
#define _MODULE_INTERFACE_H_
#ifdef WIN32
#ifdef MODULE_EXPORTS
#define MODULE_API __declspec(dllexport)
#else
#define MODULE_API __declspec(dllimport)
#endif
#else
#define MODULE_API
#endif
#define MM_MODULE_ERR_OK 1000
#define MM_MODULE_ERR_WRONG_INDEX 1001
#define MM_MODULE_ERR_BUFFER_TOO_SMALL 1002
///////////////////////////////////////////////////////////////////////////////
// header version
// NOTE: If any of the exported module API calls changes, the interface version
// must be incremented
// new version 5 supports device discoverability
#define MODULE_INTERFACE_VERSION 7
#ifdef WIN32
const char* const LIB_NAME_PREFIX = "mmgr_dal_";
#else
const char* const LIB_NAME_PREFIX = "libmmgr_dal_";
#endif
#include "MMDevice.h"
///////////////////////////////////////////////////////////////////////////////
// Exported module interface
///////////////////////////////////////////////////////////////////////////////
extern "C" {
MODULE_API MM::Device* CreateDevice(const char* name);
MODULE_API void DeleteDevice(MM::Device* pDevice);
MODULE_API long GetModuleVersion();
MODULE_API long GetDeviceInterfaceVersion();
MODULE_API unsigned GetNumberOfDevices();
MODULE_API bool GetDeviceName(unsigned deviceIndex, char* name, unsigned bufferLength);
MODULE_API bool GetDeviceDescription(const char* deviceName, char* name, unsigned bufferLength);
And here is a part of the CPP file which defines these functions
//ModuleInterface.cpp
#define _CRT_SECURE_NO_DEPRECATE
#include "ModuleInterface.h"
#include <vector>
#include <string>
typedef std::pair<std::string, std::string> DeviceInfo;
std::vector<DeviceInfo> g_availableDevices;
int FindDeviceIndex(const char* deviceName)
{
for (unsigned i=0; i<g_availableDevices.size(); i++)
if (g_availableDevices[i].first.compare(deviceName) == 0)
return i;
return -1;
}
MODULE_API long GetModuleVersion()
{
return MODULE_INTERFACE_VERSION;
}
MODULE_API long GetDeviceInterfaceVersion()
{
return DEVICE_INTERFACE_VERSION;
}
MODULE_API unsigned GetNumberOfDevices()
{
return (unsigned) g_availableDevices.size();
}
MODULE_API bool GetDeviceName(unsigned deviceIndex, char* name, unsigned bufLen)
{
if (deviceIndex >= g_availableDevices.size())
return false;
Now the problem is it gives me an error C2491 (definition of dllimport function not allowed)
I did research about this and it usually is when a function is defined when it is supposed to be declared, I have already defined the function in ModuleInterface.h and then used it in ModuleInterface.cpp but it still shows the same error.
Can there be some other possibility for this error to occur? Or is there something wrong with the code?
You're not supposed to repeat your MODULE_API declaration in the definition, having it as part of the declaration is good enough. Remove the use of MODULE_API from the .cpp file and the code should compile.

Capturing USB Plug/Unplug events in Firemonkey

[RAD Studio XE3 / C++]
I have a FMX project running in Windows only at this stage, but I need to detect events when USB devices are connected and disconnected. I have a similar VCL app that can do this fine, but the Application->HookMainWindow is not exposed in FMX (only VCL).
Is there an elegant way to handle this? Or do I have to hack some VCL stuff into my FMX app to make that work? I'd imagine I have to abstract it so I can support other platforms down the track. For the meantime though I need to get the Windows solution working.
If the 'VCL hack' thing is required, how would I reference the vcl::Forms::Application from within my Fmx app?
Cheers.
This could help, using the TMessage way?
type
TMyMessageClass = class(TMessage)
MyProp1 : Integer;
MyProp2 : string;
end;
procedure MyForm.FormCreate(Sender: TObject);
begin
TMessageManager.DefaultManager.SubscribeToMessage(TMyMessageClass, Self.ProcessMessage);
end;
procedure MyForm.ProcessMessage(Sender : TObject; M : TMessage);
begin
if M is TMyMessageClass then
begin
//Do something
end;
end;
From the thread I do something like...
procedure TMyThread.Execute;
var
FMyMessage : TMyMessageClass;
begin
//stuff
Synchronize(
procedure
begin
FMyMessageClass := TMyMessageClass.Create;
FMyMessageClass.MyProp1 := 1;
FMyMessageClass.MyProp2 := 'Hello';
TMessageManager.DefaultManager.SendMessage(nil, FMyMessageClass);
end);
Hope this helps
I have found a solution, thanks to http://www.haogongju.net/art/1480814
It'd be nice to be able to attach some files but it looks like it's going to have to go inline.
SystemEvents.h
#ifndef SystemEventsH
#define SystemEventsH
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include "DeviceChanged.h"
//---------------------------------------------------------------------------
class TSystemEvents : TObject
{
private:
TDeviceChangedMethod pDeviceChangeHandler;
TForm *pOwnerForm;
#ifdef _Windows
HWND Hwnd; // Save the window handle
LONG OldWndProc;// And remember the old WndProc so we can put it back later
#endif
public:
__fastcall TSystemEvents(TForm *_pForm);
__fastcall ~TSystemEvents();
__property TForm *OwnerForm = {read=pOwnerForm};
#ifdef _Windows
LRESULT __stdcall MessageHandler(Winapi::Messages::TMessage &Message);
#endif // _Windows
__property TDeviceChangedMethod DeviceChangeHandler={read=pDeviceChangeHandler,write=pDeviceChangeHandler};
};
extern TSystemEvents *SystemEvents;
#endif
SystemEvents.cpp
#include <fmx.h>
#include <FMX.Platform.Win.hpp>
#pragma hdrstop
#include "SystemEvents.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#ifdef _Windows
LRESULT __stdcall WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (SystemEvents == NULL)
{
return 0;
}
// This routine can't be a closure because the winapi needs to call it as
// a LONGPTR. So from here I can pass it into the SystemEvents object.
Winapi::Messages::TMessage _Message;
_Message.Msg = msg;
_Message.WParam = wParam;
_Message.LParam = lParam;
return (LRESULT)SystemEvents->MessageHandler(_Message);
}
#endif //_Windows
__fastcall TSystemEvents::TSystemEvents(TForm *_pForm)
{
pOwnerForm = _pForm;
pDeviceChangeHandler = NULL;
#ifdef _Windows
// Owner form handle is in FMX framework, but we want a Hwnd handle:
Hwnd = FmxHandleToHWND(pOwnerForm->Handle);
// Save the original WindowProc address
OldWndProc = GetWindowLongPtr(Hwnd, GWL_WNDPROC);
// Redirect the messages to my own function
SetWindowLongPtr(Hwnd, GWL_WNDPROC, (LONG_PTR)&WindowProc);
#endif
}
__fastcall TSystemEvents::~TSystemEvents()
{
#ifdef _Windows
// Very important we undo our hack before the app finishes
SetWindowLongPtr(Hwnd, GWL_WNDPROC, OldWndProc);
#endif
}
LRESULT __stdcall TSystemEvents::MessageHandler(Winapi::Messages::TMessage &Message)
{
#ifdef _Windows
if (Message.Msg == WM_DEVICECHANGE)
{
if (DeviceChangeHandler != NULL)
{
DeviceChangeHandler(this, new TDeviceChangedMessage(TDeviceChangedMessage::ParamForWin32wParam(Message.WParam)));
return 1;
}
}
return CallWindowProc((WNDPROC)OldWndProc, Hwnd, Message.Msg, Message.WParam, Message.LParam);
#endif
return 0;
}
DeviceChanged.h
#ifndef DeviceChangedH
#define DeviceChangedH
//---------------------------------------------------------------------------
typedef enum {Unknown = 0, DeviceNodesChanged} DeviceChangedParam;
class TDeviceChangedMessage
{
private:
DeviceChangedParam eParam;
public:
TDeviceChangedMessage(DeviceChangedParam _eParam)
{
eParam = _eParam;
}
__property DeviceChangedParam Param={read=eParam};
static DeviceChangedParam __fastcall ParamForWin32wParam(WPARAM _wParam);
};
typedef void __fastcall (__closure *TDeviceChangedMethod)(System::TObject* Sender, TDeviceChangedMessage* M);
#endif
DeviceChanged.cpp
#include <fmx.h>
#include <Dbt.h>
#pragma hdrstop
#include "DeviceChanged.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
DeviceChangedParam __fastcall TDeviceChangedMessage::ParamForWin32wParam(WPARAM _wParam)
{
if (_wParam == DBT_DEVNODES_CHANGED)
return DeviceChangedParam::DeviceNodesChanged;
return DeviceChangedParam::Unknown;
}
To use it:
#include <SystemEvents.h>
TSystemEvents *SystemEvents;
// In Constructor:
{
SystemEvents = new TSystemEvents(this);
SystemEvents->DeviceChangeHandler = OnDeviceChanged;
}
// In Destructor:
{
deletenullify(SystemEvents);
}
// Handler:
void __fastcall TMainForm::OnDeviceChanged(System::TObject* Sender, TDeviceChangedMessage *M)
{
if (M->Param == DeviceChangedParam::DeviceNodesChanged)
{
OnUSBDeviceChanged();
}
}
Works for me. :)

0xc000007b Error - but all DLLs are 32 bit

I am compiling my C++ code with /clr option using Visual Studio 2008 on Windows 7 32 bit OS targeting .NET Framework 3.5.
All the DLLs are 32 bit (verified using Dependency Walker).
As per my research this error comes up when 32 bit code calls 64 bit DLLs but this not the case here.
Are there any other root causes of error 0xc000007b?
Just happened to resolve this issue.
It seems that this error is not only caused by mixing 64 bit libraries in 32 bit code but also when libraries are messed up - in my case I was using binary PCRE library.
I built PCRE myself using MingW and now everything works fine.
For use .NET FW 4.0, you should use legacy activation shim code to load .NET FW as COM component
into your hosting app, like this:
Use macro
#define LEGACY_ACTIVATION_SHIM_ALLOW_LEGACY_API_FALLBACK
Sudoku.Runtime.h:
#pragma once
//
extern "C" int wWinMainCRTStartup();
Sudoku.Runtime.cpp:
// Sudoku.Runtime.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
int _runtime()
{
wWinMainCRTStartup();
return 0;
}
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
//CoInitializeEx(NULL, 0);
//CoUninitialize();
HRESULT hr;
ICorRuntimeHost *pHost = NULL;
hr = LegacyActivationShim::CorBindToRuntimeEx(NULL, NULL, STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast<LPVOID*>(&pHost));
if (!FAILED(hr))
{
IUnknown *pAppDomainPunk = NULL;
hr = pHost->CreateDomainEx(TEXT("_runtime"), NULL, NULL, &pAppDomainPunk);
if (!FAILED(hr))
{
_::_AppDomain *pDefaultDomain = NULL;
hr = pAppDomainPunk->QueryInterface(__uuidof(_::_AppDomain), reinterpret_cast<LPVOID*>(&pDefaultDomain));
if (!FAILED(hr))
{
_::_ObjectHandle *pObjHandle = NULL;
hr = pDefaultDomain->CreateInstance(_bstr_t("Sudoku"), _bstr_t("Sudoku.Runtime"), &pObjHandle);
if (!FAILED(hr))
{
VARIANT v;
VariantInit(&v);
hr = pObjHandle->Unwrap(&v);
if (!FAILED(hr))
{
_::IRuntime *pRemotingHost = NULL;
hr = v.pdispVal->QueryInterface(__uuidof(_::IRuntime), (void**) &pRemotingHost);
if (!FAILED(hr))
{
::System::Reflection::Assembly^ ra = Assembly::GetExecutingAssembly();
array<::System::Byte>^ bytes = ra->GetName()->GetPublicKeyToken();
SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, bytes->Length);
BYTE *pData;
hr = SafeArrayAccessData(psa, (void **)&pData);
if (!FAILED(hr))
{
for(int i=0; i < bytes->Length; i++) pData[i] = bytes[i];
hr = SafeArrayUnaccessData(psa);
if (!FAILED(hr))
{
pRemotingHost->Run(psa);
}
pHost->UnloadDomain(pAppDomainPunk);
}
}
pObjHandle->Release();
}
pDefaultDomain->Release();
}
pAppDomainPunk->Release();
}
pHost->Release();
}
LegacyActivationShim::CorExitProcess(0);
}
}
catch(...)
{
}
return 0;
}
stdafx.h:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
// TODO: reference additional headers your program requires here
// Exclude rarely-used stuff from Windows headers
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#import <mscorlib.tlb> auto_rename \
rename("value", "___value") \
rename("ReportEvent", "___ReportEvent") \
rename_namespace("_") \
raw_interfaces_only \
high_property_prefixes("_get","_put","_putref")
#import "..\\Public\\Sudoku.tlb" auto_rename \
rename_namespace("_") \
raw_interfaces_only \
high_property_prefixes("_get","_put","_putref")
// C RunTime Header Files
#include <tchar.h>
#include "cor.h"
#include "mscoree.h"
#include "strongname.h"
#include "Sudoku.Runtime.h"
#include "AssemblyInfo.h"
#include "Resource.h"
#define LEGACY_ACTIVATION_SHIM_ALLOW_LEGACY_API_FALLBACK
#include "LegacyActivationShimDelayLoad.h"
LegacyActivationShim.h:
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
//
// LegacyActivationShim.h
//
// This file allows simple migration from .NET Runtime v2 Host Activation APIs
// to the .NET Runtime v4 Host Activation APIs through simple shim functions.
// To use, just include this header file after the header file that declares the
// deprecated APIs you are using, and append the "LegacyActivationShim::" namespace
// in front of all deprecated API calls.
//
// For example,
// #include "mscoree.h"
// ...
// CorBindToRuntimeEx(
// NULL, NULL, 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pRH));
// becomes
// #include "mscoree.h"
// #include "LegacyActivationShim.h"
// ...
// LegacyActivationShim::CorBindToRuntimeEx(
// NULL, NULL, 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pRH));
//
// To enable fallback to the legacy APIs when v4.0 is not installed on the machine,
// define LEGACY_ACTIVATION_SHIM_ALLOW_LEGACY_API_FALLBACK before including this
// header file.
//
// To use the legacy API fallback in a delay-loaded fashion, include LegacyActivationShimDelayLoad.h
// instead.
//
Sudoku.Runtime.cs:
[Serializable]
[ComVisible(true)]
[Obfuscation(Exclude = true)]
public class Runtime : IRuntime
{
public void Run(byte[] publikKeyToken)
{
Application.Run(publikKeyToken);
}
}
[ComVisible(true)]
[Obfuscation(Exclude = true)]
public interface IRuntime
{
void Run(byte[] publikKeyToken);
}

Resources