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