1

CreateFile("\\mycomputer\mailslot\this_fails",...) 等命令失败,最后一个错误 = 53 ERROR_BAD_NETPATH

如果与任何有效或不存在的计算机名称(包括运行测试的同一台计算机)一起使用,则会失败。在这工作的计算机上,即使引用的计算机不存在或没有使用该名称创建的邮槽,它也会成功并返回邮槽句柄。请注意,如果使用不存在的计算机名称或邮槽,则句柄上的后续 WriteFiles 将失败,但 CreateFile 会成功。

但是,如果 Mailslot 引用是显式本地的,则上面的 CreateFile 将成功:“\\.\mailslot\always_works”

在安装 2018-05 累积更新之前,这适用于以前的所有 Windows 版本。特别是 KB4103721(Windows 10 家庭版)似乎是罪魁祸首。[编辑:如下面的答案所述,实际上是功能更新版本 1803 导致了此问题。]

测试客户端:(使用无参数或“.”但使用任何计算机名失败)。基于 msdn示例

语法:testclient [服务器计算机名]

    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>

    LPTSTR SlotName = TEXT("\\\\%hs\\mailslot\\sample_mailslot");

    BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage)
    {
       BOOL fResult;
       DWORD cbWritten;

       fResult = WriteFile(hSlot,
         lpszMessage,
         (DWORD) (lstrlen(lpszMessage)+1)*sizeof(TCHAR),
         &cbWritten,
         (LPOVERLAPPED) NULL);

       if (!fResult)
       {
// this failure is valid if computername is not valid
          printf("WriteFile failed with %d.\n", GetLastError());
          return FALSE;
       }

       printf("Slot written to successfully.\n");

       return TRUE;
    }

    int main(int nArgs,char * arg[])
    {
       HANDLE hFile;
       TCHAR szSlot[256];

       _stprintf (szSlot,SlotName,nArgs > 1 ? arg[1] : ".");

       _tprintf(TEXT("Writing to slot %s\n"),szSlot);
       hFile = CreateFile(szSlot,
         GENERIC_WRITE,
         FILE_SHARE_READ,
         (LPSECURITY_ATTRIBUTES) NULL,
         OPEN_EXISTING,
         FILE_ATTRIBUTE_NORMAL,
         (HANDLE) NULL);

       if (hFile == INVALID_HANDLE_VALUE)
       {
// this is the failure I'm trying to debug
          printf("CreateFile failed with %d.\n", GetLastError());
          return FALSE;
       }

       WriteSlot(hFile, TEXT("Message one for mailslot."));
       WriteSlot(hFile, TEXT("Message two for mailslot."));
       Sleep(5000);
       WriteSlot(hFile, TEXT("Message three for mailslot."));
       CloseHandle(hFile);

       return TRUE;
    }

测试服务器:(读取显示发送的消息)请注意,可能会收到重复的消息,因为 Mailslot 消息是通过所有可能的协议传输的。基于 msdn示例

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>

HANDLE hSlot;
LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");

BOOL ReadSlot()
{
    DWORD cbMessage, cMessage, cbRead;
    BOOL fResult;
    LPTSTR lpszBuffer;
    TCHAR achID[80];
    DWORD cAllMessages;
    HANDLE hEvent;
    OVERLAPPED ov;

    cbMessage = cMessage = cbRead = 0;

    hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
    if( NULL == hEvent )
        return FALSE;
    ov.Offset = 0;
    ov.OffsetHigh = 0;
    ov.hEvent = hEvent;

    fResult = GetMailslotInfo( hSlot, // mailslot handle
        (LPDWORD) NULL,               // no maximum message size
        &cbMessage,                   // size of next message
        &cMessage,                    // number of messages
        (LPDWORD) NULL);              // no read time-out

    if (!fResult)
    {
        printf("GetMailslotInfo failed with %d.\n", GetLastError());
        return FALSE;
    }

    if (cbMessage == MAILSLOT_NO_MESSAGE)
    {
        printf("Waiting for a message...\n");
        return TRUE;
    }

    cAllMessages = cMessage;

    while (cMessage != 0)  // retrieve all messages
    {
        // Create a message-number string.

        StringCchPrintf((LPTSTR) achID,
            80,
            TEXT("\nMessage #%d of %d\n"),
            cAllMessages - cMessage + 1,
            cAllMessages);

        // Allocate memory for the message.

        lpszBuffer = (LPTSTR) GlobalAlloc(GPTR,
            lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage);
        if( NULL == lpszBuffer )
            return FALSE;
        lpszBuffer[0] = '\0';

        fResult = ReadFile(hSlot,
            lpszBuffer,
            cbMessage,
            &cbRead,
            &ov);

        if (!fResult)
        {
            printf("ReadFile failed with %d.\n", GetLastError());
            GlobalFree((HGLOBAL) lpszBuffer);
            return FALSE;
        }

        // Concatenate the message and the message-number string.
        StringCbCat(lpszBuffer,
                    lstrlen((LPTSTR) achID)*sizeof(TCHAR)+cbMessage,
                    (LPTSTR) achID);

        // Display the message.
        _tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);

        GlobalFree((HGLOBAL) lpszBuffer);

        fResult = GetMailslotInfo(hSlot,  // mailslot handle
            (LPDWORD) NULL,               // no maximum message size
            &cbMessage,                   // size of next message
            &cMessage,                    // number of messages
            (LPDWORD) NULL);              // no read time-out

        if (!fResult)
        {
            printf("GetMailslotInfo failed (%d)\n", GetLastError());
            return FALSE;
        }
    }
    CloseHandle(hEvent);
    return TRUE;
}

BOOL WINAPI MakeSlot(LPTSTR lpszSlotName)
{
    hSlot = CreateMailslot(lpszSlotName,
        0,                             // no maximum message size
        MAILSLOT_WAIT_FOREVER,         // no time-out for operations
        (LPSECURITY_ATTRIBUTES) NULL); // default security

    if (hSlot == INVALID_HANDLE_VALUE)
    {
        printf("CreateMailslot failed with %d\n", GetLastError());
        return FALSE;
    }
    return TRUE;
}

void main()
{
   MakeSlot(SlotName);

   while(TRUE)
   {
      ReadSlot();
      Sleep(3000);
   }
}

读取消息的测试服务器和发送消息的测试客户端可以在同一台计算机上运行在不同的cmd shell中,也可以在不同的计算机上运行。当它失败时,它会立即失败,并且似乎是尝试解析网络路径名的问题。在同一台计算机上,\\ThisComputer\share 等文件共享可以在同一台计算机或不同的计算机上正常工作。

NetBIOS 通过 TCP/IP 为正在使用的网络适配器启用。网络适​​配器被指定为专用。防火墙被禁用以进行测试。文件和打印机共享已启用。计算机在同一个工作组中。计算机名称解析有效,即使使用 IP 地址(甚至是 127.0.0.1)也会失败。

4

3 回答 3

1

这似乎是来自 Windows 10 (1803) 的最新功能更新的问题,而不是通过 Windows 更新提供的补丁。请检查您是否使用的是 build 17134.48(也称为 1803)

尝试降级到1709。

01/09/2019:最新的 1809 Build Mailslots 再次工作

于 2018-05-16T15:39:31.587 回答
1

自去年以来,该问题已得到解决

2018 年 9 月 26 日 - KB4458469(操作系统内部版本 17134.320)

解决了使用 NetBIOS 域名时导致 NTLTEST、DCLOCATOR 或加入 Active Directory 和 SAMBA 域失败的问题。错误是“无法联系域 %domain% 的 Active Directory 域控制器 (AD DC)”。这也解决了使用邮槽进行通信的应用程序的连接问题。

于 2019-03-19T17:07:07.463 回答
0

我没有发现任何信息表明您这样做不再支持邮槽通信。我认为这是一个错误。但找出答案的唯一方法是通过 support.microsoft.com 打开支持票证。

或者你可以在这里发帖https://social.technet.microsoft.com/Forums

在我们从 Microsoft 获得任何新信息之前,每个需要邮槽的人都应该阻止功能升级 1803。

于 2018-05-16T20:51:36.740 回答