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
从动态名称和持久空间中删除服务。 对于使用 SERVICE_MULTIPLE 标志) (多个CSADDR_INFO结构表示的服务,只会删除指定的地址,并且必须与注册服务时指定的相应 CSADDR_INFO 结构完全匹配。

[in] dwControlFlags

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

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

返回值

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

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

注解

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

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

操作 Flags 服务已存在 服务不存在
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 服务)。 有关详细信息,请参阅 Service Publication 的安全问题

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

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

注意如果使用 ANSI 字符串,则在此函数返回后,lpqsRegInfo 中的 WSAQUERYSET 数据可能不包含任何结果。 这是因为此方法的 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 指定的名称空间提供程序。
有效的名称空间标识符 Null 支持所指示命名空间的所有名称空间提供程序。
NS_ALL Null 所有名称空间提供程序。
 

Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone Store 应用支持 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 应用]
目标平台 Windows
标头 winsock2.h
Library Ws2_32.lib
DLL Ws2_32.dll

另请参阅

蓝牙和 WSASetService

WSAGetLastError

WSAStartup

Winsock 函数

Winsock 参考