IExecuteCommand kann nicht für das Kontextmenü registriert werdenC++

Programme in C++. Entwicklerforum
Guest
 IExecuteCommand kann nicht für das Kontextmenü registriert werden

Post by Guest »

Ich versuche, IExecuteCommand für das Kontextmenü einer Textdatei zu registrieren. Dazu habe ich in einer DLL einen COM-Server erstellt und diesen in Windows registriert. Für die Registrierung habe ich die folgende .reg-Datei verwendet

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{0DF1F277-A2CD-4202-86AA-4C0BF1B8C5E4}\InProcServer32]
@="C:\Users\Username\OneDrive\Desktop\COM\COMIExecuteCommand.dll"
"ThreadingModel"="Apartment"

[HKEY_CLASSES_ROOT\txtfile\shell\printnamestodebugger]
@="Print names to debugger"
[HKEY_CLASSES_ROOT\txtfile\shell\printnamestodebugger\command]
"DelegateExecute"="{0DF1F277-A2CD-4202-86AA-4C0BF1B8C5E4}"
Als Ergebnis erscheint der Menüpunkt „Namen an Debugger drucken“ im Kontextmenü für Textdateien, aber wenn ich versuche, dieses Menü auszuwählen, erhalte ich Folgendes Fehler: „Klasse nicht registriert“, obwohl alle notwendigen Anweisungen zum Registrieren der COM-Komponente in der .reg-Datei geschrieben sind.
Ich teste unter Windows 10 64 Bit (DLL auch 64 bit)
Wie kann ich dafür sorgen, dass das Menü „Namen an Debugger drucken“ funktioniert? Sie können den COM-Komponentencode unten sehen:

Code: Select all

#include "pch.h"

#include 
#include 
#include 

#include 
CLSID CLSID_ShellExtension = { 0xdf1f277, 0xa2cd, 0x4202, { 0x86, 0xaa, 0x4c, 0xb, 0xf1, 0xb8, 0xc5, 0xe4 } };// {0DF1F277-A2CD-4202-86AA-4C0BF1B8C5E4}
LONG g_cObjs;
void DllAddRef() { InterlockedIncrement(&g_cObjs); }
void DllRelease() { InterlockedDecrement(&g_cObjs); }

class CShellExtension
: public IExecuteCommand
, public IInitializeCommand
, public IObjectWithSelection
{
public:
CShellExtension();
// *** IUnknown ***
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// *** IInitializeCommand ***
STDMETHODIMP Initialize(PCWSTR pszCommandName, IPropertyBag* ppb);
// *** IObjectWithSelection ***
STDMETHODIMP SetSelection(IShellItemArray* psia);
STDMETHODIMP GetSelection(REFIID riid, void** ppv);
// *** IExecuteCommand ***
STDMETHODIMP SetKeyState(DWORD grfKeyState) { return S_OK; }
STDMETHODIMP SetParameters(LPCWSTR pszParameters) { return S_OK; }
STDMETHODIMP SetPosition(POINT pt) { return S_OK; }
STDMETHODIMP SetShowWindow(int nShow) { return S_OK; }
STDMETHODIMP SetNoShowUI(BOOL fNoShowUI) { return S_OK; }
STDMETHODIMP SetDirectory(LPCWSTR pszDirectory) { return S_OK; }
STDMETHODIMP Execute();
private:
~CShellExtension();
private:
LONG m_cRef;
IShellItemArray* m_psia;
};
CShellExtension::CShellExtension()
: m_cRef(1), m_psia(NULL)
{
DllAddRef();
}
CShellExtension::~CShellExtension()
{
if (m_psia) m_psia->Release();
DllRelease();
}

// guts of shell extension go in here eventually
class CFactory : public IClassFactory
{
public:
// *** IUnknown ***
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef() { return 2; }
STDMETHODIMP_(ULONG) Release() { return 1;  }
// *** IClassFactory ***
STDMETHODIMP CreateInstance(IUnknown* punkOuter,
REFIID riid, void** ppv);
STDMETHODIMP LockServer(BOOL fLock);
};
CFactory c_Factory;
STDMETHODIMP CFactory::QueryInterface(REFIID riid, void** ppv)
{
IUnknown* punk = NULL;
if (riid == IID_IUnknown || riid == IID_IClassFactory) {
punk = static_cast(this);
}
*ppv = punk;
if (punk) {
punk->AddRef();
return S_OK;
}
else {
return E_NOINTERFACE;
}
}
STDMETHODIMP CFactory::CreateInstance(
IUnknown* punkOuter, REFIID riid, void** ppv)
{
*ppv = NULL;
if (punkOuter) return CLASS_E_NOAGGREGATION;
CShellExtension* pse = new(std::nothrow) CShellExtension();
if (!pse) return E_OUTOFMEMORY;
HRESULT hr = pse->QueryInterface(riid, ppv);
pse->Release();
return hr;
}
STDMETHODIMP CFactory::LockServer(BOOL fLock)
{
if (fLock) DllAddRef();
else       DllRelease();
return S_OK;
}

STDAPI DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
{
if (rclsid == CLSID_ShellExtension) {
return c_Factory.QueryInterface(riid, ppv);
}
*ppv = NULL;
return CLASS_E_CLASSNOTAVAILABLE;
}

STDAPI Test(REFCLSID rclsid,
REFIID riid, void** ppv)
{

return CLASS_E_CLASSNOTAVAILABLE;
}

STDAPI DllCanUnloadNow()
{
return g_cObjs ? S_OK : S_FALSE;
}

STDMETHODIMP CShellExtension::QueryInterface(
REFIID riid, void** ppv)
{
IUnknown* punk = NULL;
if (riid == IID_IUnknown || riid == IID_IExecuteCommand) {
punk = static_cast(this);
}
else if (riid == IID_IInitializeCommand) {
punk = static_cast(this);
}
else if (riid == IID_IObjectWithSelection) {
punk = static_cast(this);
}
*ppv = punk;
if (punk) {
punk->AddRef();
return S_OK;
}
else {
return E_NOINTERFACE;
}
}

STDMETHODIMP CShellExtension::SetSelection(IShellItemArray* psia)
{
if (psia) psia->AddRef();
if (m_psia) m_psia->Release();
m_psia = psia;
return S_OK;
}
STDMETHODIMP CShellExtension::GetSelection(
REFIID riid, void** ppv)
{
if (m_psia) return m_psia->QueryInterface(riid, ppv);
*ppv = NULL;
return E_NOINTERFACE;
}

STDMETHODIMP CShellExtension::Initialize(
PCWSTR pszCommandName,
IPropertyBag* ppb)
{
OutputDebugStringW(L"Command: ");
OutputDebugStringW(pszCommandName);
OutputDebugStringW(L"\r\n");
if (ppb) {
VARIANT vt;
VariantInit(&vt);
if (SUCCEEDED(ppb->Read(L"extra", &vt, NULL))) {
if (SUCCEEDED(VariantChangeType(&vt, &vt, 0, VT_BSTR))) {
OutputDebugStringW(L"extra: ");
OutputDebugStringW(vt.bstrVal);
OutputDebugStringW(L"\r\n");
}
VariantClear(&vt);
}
}
return S_OK;
}

STDMETHODIMP CShellExtension::Execute()
{
HRESULT hr;
if (m_psia) {
IEnumShellItems* pesi;
if (SUCCEEDED(hr = m_psia->EnumItems(&pesi))) {
IShellItem* psi;
while (pesi->Next(1, &psi, NULL) == S_OK) {
LPWSTR pszName;
if (SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH,
&pszName))) {
OutputDebugStringW(L"File:  ");
OutputDebugStringW(pszName);
OutputDebugStringW(L"\r\n");
CoTaskMemFree(pszName);
}
psi->Release();
}
pesi->Release();
hr = S_OK;
}
}
else {
hr = E_UNEXPECTED;
}
return hr;
}

STDMETHODIMP_(ULONG) CShellExtension::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CShellExtension::Release()
{
ULONG cRef = --m_cRef;
if (cRef == 0) delete this;
return cRef;
}

HRESULT __stdcall DllRegisterServer()
{
return S_OK;
}

HRESULT __stdcall DllUnregisterServer()
{
return S_OK;
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DEF-Datei

Code: Select all

LIBRARY COMIExecuteCommand
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post