CreateFile(" \\ mycomputer \ mailslot \ this_fails",...)等命令失败,最后一次错误= 53 ERROR_BAD_NETPATH
如果与任何有效或不存在的计算机名称(包括运行测试的同一台计算机)一起使用,则会失败。在其工作的计算机上,它成功并返回邮件槽句柄,即使引用的计算机不存在或没有使用该名称创建的邮件槽。请注意,如果使用不存在的计算机名称或邮件槽,则句柄上的后续WriteFiles将失败,但CreateFile会成功。
但是,如果Mailslot引用明确是本地的,则上面的CreateFile将成功:" \\。\ mailslot \ always_works"
在安装2018-05累积更新之前,这适用于所有版本的Windows。特别是KB4103721(Windows 10家庭)似乎是罪魁祸首。 [编辑:如下面的答案中所述,实际上是功能更新版本1803会导致此问题。]
测试客户端:(不使用参数或"。"但使用任何计算机名称失败)。 基于msdn sample
语法:testclient [server computername]
#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 sample。
#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等文件共享可以在同一台计算机或其他计算机上正常工作。
通过TCP / IP为正在使用的网络适配器启用NetBIOS。网络适配器被指定为专用。防火墙已禁用以进行测试。文件和打印机共享已启用。计算机位于同一工作组中。计算机名称解析工作,即使使用IP地址(甚至127.0.0.1)也会失败。
答案 0 :(得分:1)
这似乎是来自Windows 10(1803)的最新功能更新的问题,而不是通过Windows Update的补丁。 请检查您是否使用build 17134.48(也称为1803)
尝试降级至1709。
2019年1月9日: 随着1809年末,Build Mailslots再次运作
答案 1 :(得分:0)
我没有找到任何信息,你不会以这种方式支持邮件通信。 我认为这是一个错误。 但唯一可以找到的方法是通过support.microsoft.com打开支持票。
或者你可以在这里发帖https://social.technet.microsoft.com/Forums
在我们从Microsoft获得任何新信息之前,所有需要邮件的人都应该阻止功能升级1803.
答案 2 :(得分:0)
自去年以来该问题已得到解决
September 26, 2018—KB4458469 (OS Build 17134.320)
解决了导致NTLTEST,DCLOCATOR或加入 使用NetBIOS时Active Directory和SAMBA域失败 域名。错误是“ Active Directory域控制器(AD DC%domain%的域无法连接”。 这也是 解决了使用邮筒来连接应用程序的连接问题 交流。