Winapi 将我自己的界面添加到deskband

Winapi 将我自己的界面添加到deskband,winapi,com,proxy,atl,deskband,Winapi,Com,Proxy,Atl,Deskband,我正在Windows7SP1x64上使用VisualStudio2010 我需要制作一个与win32应用程序通信的自定义deskband,编译为32位应用程序 我将这篇CodeProject文章作为起点: deskband dll(为x64编译)工作正常-我在任务栏中看到它,等等 它是使用regsvr32从“以管理员身份运行”的cmd.exe注册的。rgs文件如下所示: HKCR { NoRemove CLSID { ForceRemove {8D330AEA-9

我正在Windows7SP1x64上使用VisualStudio2010

我需要制作一个与win32应用程序通信的自定义deskband,编译为32位应用程序

我将这篇CodeProject文章作为起点:

deskband dll(为x64编译)工作正常-我在任务栏中看到它,等等

它是使用regsvr32从“以管理员身份运行”的cmd.exe注册的。rgs文件如下所示:

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {8D330AEA-90D1-4632-804B-4710F2358A18} = s 'my deskbar'
        {
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Apartment'
            }
        }
    }
}
基于此答案:

我在IDL文件中创建了一个接口:

import "oaidl.idl";
import "ocidl.idl";

[
object,
uuid(35662650-07D0-4F31-B5F0-3C21FCA4BDA2),
version(1.0),
oleautomation
//dual,
//pointer_default(unique)
]
interface IGEDeskBand : IDispatch
{
        HRESULT BadgeSet([in] long arg);
        HRESULT BadgeClear(void);
        HRESULT BadgeBlink(void);
};

[
    uuid(33EB8C00-F66A-493C-8607-529060FAA378),
    version(1.0),
    helpstring("GamEffective DeskBand Library")
]
library GEDeskBandLib
{
  importlib("stdole32.tlb");

    [
        uuid(8D330AEA-90D1-4632-804B-4710F2358A18),
        helpstring("GEDeskBand Class")
    ]
    coclass GEDeskBand
    {
        [default] interface IGEDeskBand;
    };

  cpp_quote("const size_t MAX_GUID_STRING_LEN = 39;")
};
,VisualStudio使用midl编译它,生成生成标题,我包含生成的代码:
#include“GEDeskBand_I.h”
,并使我的类从

public IDispatchImpl<IGEDeskBand, &__uuidof(IGEDeskBand), &LIBID_GEDeskBandLib, /* wMajor = */ 1, /* wMinor = */ 0>
(我使用了VisualStudio向导:类视图->右键单击类,添加->实现接口),目前方法的实现只是
returne\u NOTIMPL,我希望这不是问题。这就是我对服务器上的代码所做的一切,关于我的接口,以及尝试从另一个进程与这个对象通信

使用本文()中的
#define(定义)ATL(u DEBUG)QI
,我在Visual Studio的输出窗口中看到,当连接到explorer.exe(其中加载了deskbar dll并且我的COM对象存在)时,QueryInterface会使用正确的接口进行查询,并且不会显示“失败”

此时将加载deskbar:

CComClassFactory - IClassFactory
CGEDeskBand - IDeskBand
CGEDeskBand - IPersistStreamInit
CGEDeskBand - IDeskBand2
CGEDeskBand - IDeskBand
CGEDeskBand - {EA5F2D61-E008-11CF-99CB-00C04FD64497} - failed
CGEDeskBand - IObjectWithSite
CGEDeskBand - {7FE80CC8-C247-11D0-B93A-00A0C90312E1} - failed
CGEDeskBand - IOleCommandTarget - failed
CGEDeskBand - IDeskBandInfo - failed
CGEDeskBand - IDeskBand
CGEDeskBand - IOleWindow
CGEDeskBand - IPersist
CGEDeskBand - IDeskBand2
这就是我运行测试仪来演示问题的时候:

CGEDeskBand - IDeskBand
CGEDeskBand - {00000003-0000-0000-C000-000000000046} - failed
CGEDeskBand - {00000003-0000-0000-C000-000000000046} - failed
CGEDeskBand - {0000001B-0000-0000-C000-000000000046} - failed
CGEDeskBand - IUnknown
CGEDeskBand - {00000018-0000-0000-C000-000000000046} - failed
CGEDeskBand - {00000019-0000-0000-C000-000000000046} - failed
CGEDeskBand - {4C1E39E1-E3E3-4296-AA86-EC938D896E92} - failed
CGEDeskBand - IDeskBand
CGEDeskBand - IDeskBand
CGEDeskBand - IPersist
CGEDeskBand - IPersist
CGEDeskBand - {1C733A30-2A1C-11CE-ADE5-00AA0044773D} - failed
CGEDeskBand - {35662650-07D0-4F31-B5F0-3C21FCA4BDA2}
#include <Shobjidl.h>
#include "GEDeskBand_i.h"
#include "GEDeskBandGuids.h"

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr;
    CComPtr<IUnknown> spBandService;
    CComPtr<IBandSite> spBandSite;
    CoInitialize(NULL);
    hr = spBandService.CoCreateInstance(CLSID_TrayBandSiteService);
    if (SUCCEEDED(hr)) {
        hr = spBandService->QueryInterface(&spBandSite);
        if (SUCCEEDED(hr)) {
            DWORD dwBandId = 0;
            UINT num_bands = spBandSite->EnumBands((UINT)-1, &dwBandId);
            for (UINT uBand = 0; uBand < num_bands; uBand++) {
                if (SUCCEEDED(spBandSite->EnumBands(uBand, &dwBandId))) {
                    IDeskBand *band;
                    if (SUCCEEDED(spBandSite->GetBandObject(dwBandId, IID_IDeskBand, (void**)&band))) {
                        IPersist* pPersist = NULL;
                        if (SUCCEEDED(band->QueryInterface(IID_IPersist, (void**)&pPersist))) {
                            CLSID clsid = CLSID_NULL;
                            if (SUCCEEDED(pPersist->GetClassID(&clsid))) {
                                if (clsid == CLSID_GEDeskBand) {
                                    // reaches here fine
                                    IGEDeskBand *pGEDeskBand = NULL;
                                    hr = band->QueryInterface(IID_IGEDeskBand, (void**)&pGEDeskBand);
                                    if (SUCCEEDED(hr)) {
                                        // never reaches here, always get E_NOINTERFACE
                                        pGEDeskBand->BadgeSet(1);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            spBandSite.Release();
        }
        spBandService.Release();
    }
    CoUninitialize();
    return 0;
}
最后一个是我的身份证,上面没有说失败

这是演示问题的测试代码:

CGEDeskBand - IDeskBand
CGEDeskBand - {00000003-0000-0000-C000-000000000046} - failed
CGEDeskBand - {00000003-0000-0000-C000-000000000046} - failed
CGEDeskBand - {0000001B-0000-0000-C000-000000000046} - failed
CGEDeskBand - IUnknown
CGEDeskBand - {00000018-0000-0000-C000-000000000046} - failed
CGEDeskBand - {00000019-0000-0000-C000-000000000046} - failed
CGEDeskBand - {4C1E39E1-E3E3-4296-AA86-EC938D896E92} - failed
CGEDeskBand - IDeskBand
CGEDeskBand - IDeskBand
CGEDeskBand - IPersist
CGEDeskBand - IPersist
CGEDeskBand - {1C733A30-2A1C-11CE-ADE5-00AA0044773D} - failed
CGEDeskBand - {35662650-07D0-4F31-B5F0-3C21FCA4BDA2}
#include <Shobjidl.h>
#include "GEDeskBand_i.h"
#include "GEDeskBandGuids.h"

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr;
    CComPtr<IUnknown> spBandService;
    CComPtr<IBandSite> spBandSite;
    CoInitialize(NULL);
    hr = spBandService.CoCreateInstance(CLSID_TrayBandSiteService);
    if (SUCCEEDED(hr)) {
        hr = spBandService->QueryInterface(&spBandSite);
        if (SUCCEEDED(hr)) {
            DWORD dwBandId = 0;
            UINT num_bands = spBandSite->EnumBands((UINT)-1, &dwBandId);
            for (UINT uBand = 0; uBand < num_bands; uBand++) {
                if (SUCCEEDED(spBandSite->EnumBands(uBand, &dwBandId))) {
                    IDeskBand *band;
                    if (SUCCEEDED(spBandSite->GetBandObject(dwBandId, IID_IDeskBand, (void**)&band))) {
                        IPersist* pPersist = NULL;
                        if (SUCCEEDED(band->QueryInterface(IID_IPersist, (void**)&pPersist))) {
                            CLSID clsid = CLSID_NULL;
                            if (SUCCEEDED(pPersist->GetClassID(&clsid))) {
                                if (clsid == CLSID_GEDeskBand) {
                                    // reaches here fine
                                    IGEDeskBand *pGEDeskBand = NULL;
                                    hr = band->QueryInterface(IID_IGEDeskBand, (void**)&pGEDeskBand);
                                    if (SUCCEEDED(hr)) {
                                        // never reaches here, always get E_NOINTERFACE
                                        pGEDeskBand->BadgeSet(1);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            spBandSite.Release();
        }
        spBandService.Release();
    }
    CoUninitialize();
    return 0;
}
#包括
#包括“GEDeskBand_i.h”
#包括“GEDeskBandGuids.h”
int _tmain(int argc,_TCHAR*argv[]
{
HRESULT-hr;
客户服务;
Cmptr spBandSite;
共初始化(空);
hr=spBandService.CoCreateInstance(CLSID_TrayBandSiteService);
如果(成功(hr)){
hr=spBandService->QueryInterface(&spBandSite);
如果(成功(hr)){
DWORD dwBandId=0;
UINT num_bands=spBandSite->EnumBands((UINT)-1和dwBandId);
对于(UINT uBand=0;uBandEnumBands(uBand和dwBandId))){
IDeskBand*波段;
如果(成功(spBandSite->GetBandObject(dwBandId,IID_IDeskBand,(void**)和band))){
IPersist*pPersist=NULL;
if(成功(带->查询接口(IID_IPersist,(void**)和pPersist))){
CLSID CLSID=CLSID_NULL;
if(成功(pPersist->GetClassID(&clsid))){
if(clsid==clsid\u GEDeskBand){
//到达这里很好
IGEDeskBand*pGEDeskBand=NULL;
hr=波段->查询界面(IID_IGESKBAND,(void**)和pGEDeskBand);
如果(成功(hr)){
//永远不要到达这里,永远不要面对面
pGEDeskBand->徽章集(1);
}
打破
}
}
}
}
}
}
spBandSite.Release();
}
spBandService.Release();
}
coninitialize();
返回0;
}
问题是,尽管我看到了DeskBand对象的IDeskBand或IPersist(CLSID匹配,我知道它是我的对象,并且我知道它实现了该接口),但使用接口IID_DeskBand的QueryInterface永远不会成功

QueryInterface确实找到了IID,但我的客户没有收到。我想是因为编组的缘故吧

我曾尝试将测试仪编译为x64,但没有成功

陈雷蒙写道:

从那篇博文中我所了解到的是,我需要处理编组。我以为它应该是自动的

我发现解决这个问题的一种方法是构建一个midl生成的代理存根:

通过让midl在此处创建32位代理代码和配方,我构建并注册了一个32位代理存根dll:

这也不起作用-在运行测试程序时,我没有看到在测试程序进程中加载代理存根DLL。我应该吗?它似乎注册正确


我对COM甚至通用win32都不太了解,但我已经在谷歌上搜索了几个小时,我不明白我做错了什么。

如果你不展示它是如何在COM服务器端制作的,问题可能就在那里。调用应该到达您的COM对象,然后从那里失败。我在COM服务器端添加了一些关于代码的详细信息,是的,调用到达QueryInterface,在那里成功,然后从那里失败,这正是封送处理不起作用时的方式。这应该很简单。创建inproc服务器时,封送是真正的原因,但只有当COM类注册为“免费”单元模型时,封送才有问题。我想说的是,它仍然存在于COM类定义中,
COM\u INTERFACE\u xxx
映射或对类型库的错误引用,或缺少/未注册的类型库。你不应该陷入这样的麻烦,除非你在路上已经犯了一个错误。我同意我认为这应该很简单。我认为这不是COM映射,因为QueryInterface部分工作正常。我没有更改对tlb的任何引用。事实上,我看到在属性页->配置属性->midl->输出->生成类型库下设置为“否”。但是DLL的创建和注册都很好(正如我所说的,deskband可以正常工作)。