Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何查找WSD打印机的IP地址?我想使用WSDAPI,但无法使用IWSDDiscoveredDevice_C++ - Fatal编程技术网

C++ 如何查找WSD打印机的IP地址?我想使用WSDAPI,但无法使用IWSDDiscoveredDevice

C++ 如何查找WSD打印机的IP地址?我想使用WSDAPI,但无法使用IWSDDiscoveredDevice,c++,C++,我已经尝试过WSDDeviceProxy&在这个特别的GetMetadata中,我获得了除IP地址之外的所有打印机信息。在一个网站上,我读到IP可以通过IWSDiscoveredDevice获得,但如何创建IWSDiscoveredDevice?不久前,我遇到了一个类似的问题:找到已安装WSD打印队列的传输地址。最好从阅读规范开始 如果处理已安装的WSD打印机队列,则您具有打印机UUID,只需发送解析请求并侦听ResolveMatch响应即可。最简单实用的方法是: 通过EnumPrinters获

我已经尝试过WSDDeviceProxy&在这个特别的GetMetadata中,我获得了除IP地址之外的所有打印机信息。在一个网站上,我读到IP可以通过IWSDiscoveredDevice获得,但如何创建IWSDiscoveredDevice?

不久前,我遇到了一个类似的问题:找到已安装WSD打印队列的传输地址。最好从阅读规范开始

如果处理已安装的WSD打印机队列,则您具有打印机UUID,只需发送解析请求并侦听ResolveMatch响应即可。最简单实用的方法是:

  • 通过EnumPrinters获取打印机队列端口名(我使用的是级别5)
  • 通过EnumPorts获取端口监视器
  • 从注册表路径获取“打印机UUID”
  • 计算机\HKEY\U本地\U机器\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD 端口\端口

  • 使用utf-8编码数据将UDP数据包发送到地址239.255.255.250端口3702

            <soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" 
              xmlns:wsa=""http://schemas.xmlsoap.org/ws/2004/08/addressing""
              xmlns:wsd=""http://schemas.xmlsoap.org/ws/2005/04/discovery"">
                <soap:Header>
                    <wsa:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To>
                    <wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Resolve</wsa:Action>
                    <wsa:MessageID>{0}</wsa:MessageID>
                </soap:Header>
                <soap:Body>
                    <wsd:Resolve>
                        <wsa:EndpointReference>
                            <wsa:Address>{1}</wsa:Address>
                        </wsa:EndpointReference>
                    </wsd:Resolve>
                </soap:Body>
            </soap:Envelope>"
    
    
    urn:schemasxmlsoap org:ws:2005:04:discovery
    http://schemas.xmlsoap.org/ws/2005/04/discovery/Resolve
    {0}
    {1}
    "
    
  • 其中messageId是
    urn:uuid:
    ,地址是
    urn:uuid:

  • 接收UDP单播响应

  • 传输地址存储在

  • 解析匹配示例:

     <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:wsd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdp="http://schemas.xmlsoap.org/ws/2006/02/devprof" xmlns:wsvc0="http://schemas.microsoft.com/windows/2006/08/wdp/scan" xmlns:wsvc1="http://schemas.microsoft.com/windows/2006/08/wdp/print">
        <soap:Header>
            <wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/ResolveMatches</wsa:Action>
            <wsa:MessageID>urn:uuid:d8a491ad-0d87-4429-b900-84f102a91097</wsa:MessageID>
            <wsa:RelatesTo>urn:uuid:8fc371bb-edfb-49a4-b631-7e5264e25c20</wsa:RelatesTo>
            <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
            <wsd:AppSequence InstanceId="1529651446" MessageNumber="1790"/>
        </soap:Header>
        <soap:Body>
            <wsd:ResolveMatches>
                <wsd:ResolveMatch>
                    <wsa:EndpointReference>
                        <wsa:Address>urn:uuid:edec3c87-cfbc-4b02-bcb8-077be723bd32</wsa:Address>
                    </wsa:EndpointReference>
                    <wsd:XAddrs>http://192.168.1.101:65001 http://[fe80::221:b7ff:fe19:8a4a]:65001</wsd:XAddrs>
                    <wsd:MetadataVersion>168</wsd:MetadataVersion>
                </wsd:ResolveMatch>
            </wsd:ResolveMatches>
        </soap:Body>
    </soap:Envelope>
    
    
    http://schemas.xmlsoap.org/ws/2005/04/discovery/ResolveMatches
    urn:uuid:d8a491ad-0d87-4429-b900-84f102a91097
    urn:uuid:8fc371bb-edfb-49a4-b631-7e5264e25c20
    http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
    urn:uuid:edec3c87-cfbc-4b02-bcb8-077be723bd32
    http://192.168.1.101:65001 http://[fe80::221:b7ff:fe19:8a4a]:65001
    168
    
    如果不处理已安装的打印队列,则必须执行探测请求,侦听ProbeMatch,然后再转到Resolve/ResolveMatch

    我最终得到了200条生产线的完全管理的最小解决方案。如果您正在寻找WSDAAPI,请看下面的示例(只是一个想法,肯定还没有准备好生产):

    WSDiscoveryProviderNotifier.cpp:

    #include <Wsdapi.h>
    #include <Wsddisco.h>
    #include "guid_helper.h"
    import std.core;
    
    constexpr const IID IID_WSDiscoveryProviderNotifier = guid_parse::make_guid("{EFECF0A1-399E-40B8-A13C-ACE28DB40212}");
    
    class WSDiscoveryProviderNotifier : public IWSDiscoveryProviderNotify {
    private:
        LONG referenceCount = 0;
    public:
        /* IUnknown */
        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj) override {
            // Always set out parameter to NULL, validating it first.
            if (!ppvObj)
                return E_INVALIDARG;
            *ppvObj = nullptr;
            if (riid == IID_IUnknown || riid == IID_WSDiscoveryProviderNotifier) {
                // Increment the reference count and return the pointer.
                *ppvObj = (LPVOID) this;
                AddRef();
                return NOERROR;
            }
            return E_NOINTERFACE;
        }
    
        ULONG STDMETHODCALLTYPE AddRef() override {
            InterlockedIncrement(&referenceCount);
            return referenceCount;
        };
    
        ULONG STDMETHODCALLTYPE Release() override {
            ULONG ulRefCount = InterlockedDecrement(&referenceCount);
            if (0 == ulRefCount)
            {
                delete this;
            }
            return ulRefCount;
        };
    
        /* IWSDiscoveryProviderNotify */
        HRESULT STDMETHODCALLTYPE SearchFailed(
                /* [in] */ HRESULT hr,
                /* [annotation][optional][in] */
                           _In_opt_  LPCWSTR pszTag) override {
            std::wcout << "Search failed" << std::endl;
            return S_OK;
        }
    
        HRESULT STDMETHODCALLTYPE SearchComplete(
                /* [annotation][optional][in] */
                _In_opt_  LPCWSTR pszTag) override {
            std::wcout << "Search completed" << std::endl;;
            return S_OK;
        }
    
        HRESULT STDMETHODCALLTYPE Add (/* [in] */ IWSDiscoveredService *pService) override {
            WSD_URI_LIST *uriList;
            pService->GetXAddrs(&uriList);
            WSD_URI_LIST *currentElement = uriList;
            do {
                std::wcout << currentElement->Element << std::endl;
                currentElement = currentElement->Next;
            }
            while (currentElement != nullptr);
            return S_OK;
        }
    
        HRESULT STDMETHODCALLTYPE Remove(/* [in] */ IWSDiscoveredService *pService) override {
            return S_OK;
        };
    };
    
    #包括
    #包括
    #包括“guid\u helper.h”
    进口标准型芯;
    constexpr const IID IID_WSDiscoveryProviderNotifier=guid_parse::make_guid(“{EFECF0A1-399E-40B8-A13C-ACE28DB40212}”);
    类WSDiscoveryProviderNotifyer:公共IWSDiscoveryProviderNotify{
    私人:
    长引用计数=0;
    公众:
    /*IUnknown*/
    HRESULT STDMETHODCALLTYPE查询接口(refid riid,LPVOID*ppvObj)重写{
    //始终将参数设置为NULL,首先验证它。
    如果(!ppvObj)
    返回E_INVALIDARG;
    *ppvObj=nullptr;
    如果(riid==IID|IUnknown | riid==IID|WSDiscoveryProviderNotifier){
    //递增引用计数并返回指针。
    *ppvObj=(LPVOID)此;
    AddRef();
    返回无错误;
    }
    返回E_NOINTERFACE;
    }
    ULONG STDMETHODCALLTYPE AddRef()重写{
    联锁增量(和参考计数);
    返回参考计数;
    };
    ULONG STDMETHODCALLTYPE Release()重写{
    ULONG ulRefCount=联锁计数(&referenceCount);
    如果(0==ulRefCount)
    {
    删除此项;
    }
    返回ulRefCount;
    };
    /*IWSDiscoveryProviderNotify*/
    HRESULT STDMETHODCALLTYPE搜索失败(
    /*[in]*/HRESULT hr,
    /*[注释][可选][中]*/
    _In_opt_LPCWSTR pszTag)覆盖{
    标准::wcout
    
    #include <Wsdxml.h>
    #include "WSDiscoveryProviderNotifier.cpp"
    
    void ResolveWSDDeviceById(LPCWSTR deviceId) {
        HRESULT hr = S_OK;
        IWSDXMLContext *context = nullptr;
        IWSDiscoveryProvider *discoveryProvider = nullptr;
        IWSDiscoveryProviderNotify *providerNotifier = new WSDiscoveryProviderNotifier();
    
        hr = WSDCreateDiscoveryProvider(context, &discoveryProvider);
        if (S_OK == hr) {
            std::wcout << "WSDCreateDiscoveryProvider reported success" << std::endl;
            discoveryProvider->Attach(providerNotifier);
            discoveryProvider->SearchById(deviceId, nullptr);
        } else {
            throw std::exception("Failed to create IWSDiscoveryProvider");
        }
    }
    
    int main() {
        std::cout << "Hello, World!" << std::endl;
        ResolveWSDDeviceById(L"urn:uuid:edec3c87-cfbc-4b02-bcb8-077be723bd32");
        std::string _;
        std::getline (std::cin,_);
        return 0;
    }