首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何找出WSD打印机的IP地址?我想使用WSD,但无法使用IWSDDiscoveredDevice。

如何找出WSD打印机的IP地址?我想使用WSD,但无法使用IWSDDiscoveredDevice。
EN

Stack Overflow用户
提问于 2014-11-20 07:34:48
回答 1查看 2.6K关注 0票数 1

我尝试过使用WSDDeviceProxy &在这个特别是GetMetadata中,除了IP地址之外,我正在获取所有打印机信息。在一个网站上,我读到IP可以通过IWSDDiscoveredDevice,但是如何创建IWSDDiscoveredDevice呢?

EN

回答 1

Stack Overflow用户

发布于 2020-09-02 12:52:55

不久前,我遇到了一个类似的问题:查找已安装的WSD打印队列的传输地址。从这里开始的好一点是阅读规范:http://docs.oasis-open.org/ws-dd/discovery/1.1/wsdd-discovery-1.1-spec.pdf

如果您处理已安装的WSD打印机队列,则您有打印机UUID,并且可以简单地发送一个解决请求并侦听ResolveMatch响应。最简单的实用方法是:

  1. 通过EnumPrinters获取打印机队列端口名(我使用了第5级)
  2. 通过EnumPorts获取端口监视器
  3. 从注册表路径获取“打印机UUID”

Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD Port\Ports

  1. 发送UDP数据包到带有utf-8编码数据的239.255.255.250端口3702 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""> http://schemas.xmlsoap.org/ws/2005/04/discovery/Resolve {0} {1} “

其中messageId是urn:uuid:<GENERATED_GUID>,地址是urn:uuid:<PRINTER_UUID>

  1. 接收UDP单播响应

  1. 传送地址存储在<wsd:XAddrs>中。

示例ResolveMatch:

代码语言:javascript
复制
 <?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>

如果您不处理已安装的打印队列,则必须执行一个探测请求,侦听ProbeMatch,然后才进行解析/ ResolveMatch。

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

WSDiscoveryProviderNotifier.cpp:

代码语言:javascript
复制
#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;
    };
};

main.cpp:

代码语言:javascript
复制
#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;
}

希望这能帮上忙。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27034167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档