WSASetServiceA 函数 (winsock2.h)

WSASetService 函数在一个或多个命名空间内的服务实例的注册表中注册或删除。

语法

INT WSAAPI WSASetServiceA(
  [in] LPWSAQUERYSETA   lpqsRegInfo,
  [in] WSAESETSERVICEOP essoperation,
  [in] DWORD            dwControlFlags
);

参数

[in] lpqsRegInfo

指向注册或取消注册的服务信息的指针。

[in] essoperation

确定请求的操作的值。 此参数可以是 Winsock2.h 头文件中定义的 WSAESETSERVICEOP 枚举类型中的值之一。

价值 意义
RNRSERVICE_REGISTER
注册服务。 对于 SAP,这意味着发送定期广播。 这是 DNS 命名空间的 NOP。 对于持久性数据存储,这意味着更新地址信息。
RNRSERVICE_DEREGISTER
从注册表中删除服务。 对于 SAP,这意味着停止发送定期广播。 这是 DNS 命名空间的 NOP。 对于持久性数据存储,这意味着删除地址信息。
RNRSERVICE_DELETE
从动态名称和永久性空格中删除服务。 对于由多个 CSADDR_INFO 结构(使用SERVICE_MULTIPLE标志)表示的服务,只会删除指定的地址,并且必须与注册服务时指定的相应 CSADDR_INFO 结构完全匹配。

[in] dwControlFlags

服务安装标志值,用于进一步控制 WSASetService 函数执行的操作。 此参数的可能值在 Winsock2.h 头文件中定义。

意义
SERVICE_MULTIPLE
控制操作范围。 如果未设置此标志,服务地址将作为组进行管理。 在添加给定地址集之前,注册表中的寄存器或删除会使所有现有地址失效。 设置时,仅对给定地址集执行该操作。 寄存器不会使现有地址失效,并且从注册表中删除只会使给定的地址集失效。

返回值

如果操作成功,则 WSASetService 的返回值为零。 否则,返回值SOCKET_ERROR,可以通过调用 WSAGetLastError来检索特定的错误号。

错误代码 意义
WSAEACCES
调用例程没有足够的权限来安装服务。
WSAEINVAL
一个或多个必需的参数无效或缺失。
WSANOTINITIALIZED
尚未初始化 Ws2_32.dll。 在调用任何 Windows 套接字函数之前,应用程序必须先调用 WSAStartup
WSA_NOT_ENOUGH_MEMORY
内存不足,无法执行操作。

言论

WSASetService 函数可用于影响特定命名空间提供程序、与特定命名空间关联的所有提供程序或所有命名空间中的所有提供程序。

essOperationdwControlFlags 的可用值组合在一起,用于控制 WSASetService 函数的操作,如下表所示。

操作 标志 服务已存在 服务不存在
RNRSERVICE_REGISTER 没有 覆盖对象。 仅使用指定的地址。 对象为 REGISTERED。 创建新对象。 仅使用指定的地址。 对象为 REGISTERED。
RNRSERVICE_REGISTER SERVICE_MULTIPLE 更新对象。 将新地址添加到现有集。 对象为 REGISTERED。 创建新对象。 使用指定的所有地址。 对象为 REGISTERED。
RNRSERVICE_DEREGISTER 没有 删除所有地址,但不从命名空间中删除对象。 对象将从注册表中删除。 WSASERVICE_NOT_FOUND
RNRSERVICE_DEREGISTER SERVICE_MULTIPLE 更新对象。 仅删除指定的地址。 仅当不存在地址时,才会将对象标记为 DEREGISTERED。 不从命名空间中删除对象。 WSASERVICE_NOT_FOUND
RNRSERVICE_DELETE 没有 从命名空间中删除对象。 WSASERVICE_NOT_FOUND
RNRSERVICE_DELETE SERVICE_MULTIPLE 仅删除指定的地址。 仅当没有地址保留时,才会从命名空间中删除对象。 WSASERVICE_NOT_FOUND
 

根据访问控制列表(ACL)将服务发布到目录(如 Active Directory 服务)受到限制。 有关详细信息,请参阅服务发布安全问题。

dwControlFlags 参数设置为 SERVICE_MULTIPLE时,应用程序可以独立管理其地址。 当应用程序想要单独管理其协议或服务驻留在多台计算机上时,这非常有用。 例如,当服务使用多个协议时,可能会发现一个侦听套接字中止,但其他套接字仍可正常运行。 在这种情况下,服务可以从注册表中删除中止的地址,而不会影响其他地址。

dwControlFlags 参数设置为 SERVICE_MULTIPLE时,应用程序不得让过时的地址保留在对象中。 如果应用程序中止而不发出 DEREGISTER 请求,则可能会发生这种情况。 服务注册时,应存储其地址。 在下一次调用中,服务应在注册新地址之前从注册表中显式删除这些旧的过时地址。

注意 如果使用 ANSI 字符串,则可能 WSAQUERYSETlpqsRegInfo 中的数据 在此函数返回后可能不包含任何结果。 这是因为此方法的 ANSI 版本(WSASetServiceA)在内部将 WSAQUERYSET 中的 ANSI 数据转换为 Unicode,但不会将结果转换回 ANSI。 这主要影响返回用于唯一标识记录的“服务记录句柄”的传输。 若要解决此问题,应用程序应在调用此函数时 WSAQUERYSET 中使用 Unicode 字符串数据。
 

服务属性

下表介绍了如何在 WSAQUERYSET 结构中表示服务属性数据。 标记为(可选)的字段可以包含 null 指针。
WSAQUERYSET 成员 服务属性说明
dwSize 必须设置为 sizeof (WSAQUERYSET)。 这是版本控制机制。
dwOutputFlags 不适用且被忽略。
lpszServiceInstanceName 引用的字符串包含服务实例名称。
lpServiceClassId 与此服务类对应的 GUID。
lpVersion (可选)提供服务实例版本号。
lpszComment (可选)可选注释字符串。
dwNameSpace 请参阅下表。
lpNSProviderId 请参阅下表。
lpszContext (可选)指定分层命名空间中查询的起点。
dwNumberOfProtocols 忽视。
lpafpProtocols 忽视。
lpszQueryString 忽视。
dwNumberOfCsAddrs lpcsaBuffer引用的 CSADDR_INFO 结构数组中的元素数。
lpcsaBuffer 指向包含服务正在侦听的地址(es)的 CSADDR_INFO 结构的数组的指针。
lpBlob (可选)这是指向提供程序特定实体的指针。
 

如下所述,dwNameSpacelpNSProviderId 成员的组合决定了命名空间提供程序受此函数的影响。

dwNameSpace lpNSProviderId 影响范围
忽视 非 null 指定的名称空间提供程序。
有效的名称 - 空间标识符 支持所指示命名空间的所有名称空间提供程序。
NS_ALL 所有名称空间提供程序。
 

Windows Phone 8: Windows Phone 8 及更高版本的 Windows Phone 应用商店应用支持 WSASetServiceW 功能。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本上的 Windows 应用商店应用支持 WSASetServiceW 函数。

注意

winsock2.h 标头将 WSASetService 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的 约定。

要求

要求 价值
最低支持的客户端 Windows 8.1、Windows Vista [桌面应用 |UWP 应用]
支持的最低服务器 Windows Server 2003 [桌面应用 |UWP 应用]
目标平台 窗户
标头 winsock2.h
Ws2_32.lib
DLL Ws2_32.dll

另请参阅

蓝牙和 WSASetService

WSAGetLastError

WSAStartup

Winsock 函数

Winsock 参考