使用VMWare的Mac上的Windows 7。 GetComputerName返回ERROR_BUFFER_OVERFLOW(111)但有效长度为16且为空名称。任何想法为什么会失败?它可以与其他Windows模拟一起正常工作。
以下是演示失败的控制台应用程序的代码:
// GetComputerName.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <string> // for string
#include <vector> // for vector
using std::vector;
using std::string;
#ifdef _UNICODE
using std::wstring;
#define string wstring
using std::wostringstream;
#define ostringstream wostringstream
#else
#endif
typedef vector<TCHAR> VTChar; // vtc
CWinApp theApp; // The one and only application object
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
TCHAR tcLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1]= {_T('\0')};
DWORD dwComputerNameLength(MAX_COMPUTERNAME_LENGTH);
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
string strErrorFormat(_T("GetComputerName failed with %d; returned length was %d."));
VTChar vtcError(strErrorFormat.size() + 20, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strErrorFormat.c_str(), ::GetLastError(), dwComputerNameLength);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
else
{
string strFormat(_T("GetComputerName returned \"%s\""));
VTChar vtcError(strFormat.size() + 30, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strFormat.c_str(), tcLocalComputerName);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
return 0;
}
一位同事用了一段时间,发现如果我们再打一次电话就可以了。正在工作的应用程序实际上以迂回的方式做到了。
以下是实际运行的控制台应用程序的代码:
// GetComputerName.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <string> // for string
#include <vector> // for vector
using std::vector;
using std::string;
#ifdef _UNICODE
using std::wstring;
#define string wstring
using std::wostringstream;
#define ostringstream wostringstream
#else
#endif
typedef vector<TCHAR> VTChar; // vtc
CWinApp theApp; // The one and only application object
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
bool gotName(false);
TCHAR tcLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1]= {_T('\0')};
DWORD dwComputerNameLength(MAX_COMPUTERNAME_LENGTH);
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
AfxMessageBox(_T("First GetComputerName failed."));
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
string strErrorFormat(_T("GetComputerName failed with %d; returned length was %d."));
VTChar vtcError(strErrorFormat.size() + 20, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strErrorFormat.c_str(), ::GetLastError(), dwComputerNameLength);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
else
gotName= true;
}
else
gotName= true;
if(gotName)
{
string strFormat(_T("GetComputerName returned \"%s\""));
VTChar vtcError(strFormat.size() + 30, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strFormat.c_str(), tcLocalComputerName);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
return 0;
}
答案 0 :(得分:3)
调试Windows API调用时,您必须在通话失败后立即致电::GetLastError()
。
不是这个:
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
string strErrorFormat(_T("GetComputerName failed with %d; returned length was %d."));
VTChar vtcError(strErrorFormat.size() + 20, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strErrorFormat.c_str(), ::GetLastError(), dwComputerNameLength);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
但是这个:
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
DWORD apiError = ::GetLastError();
string strErrorFormat(_T("GetComputerName failed with %d; returned length was %d."));
VTChar vtcError(strErrorFormat.size() + 20, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strErrorFormat.c_str(), apiError, dwComputerNameLength);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
像声明一样简单的字符串变量,可以覆盖线程的最后错误值。怎么样?好吧,std::string
动态分配一个缓冲区来保存内容。动态分配需要调用分配器,分配器可能在其内部堆中有足够的空间,或者可能需要增加堆。如果需要增加堆,则会使用OS调用来执行此操作,现在您正在查看::VirtualAlloc
而不是::GetComputerName
的最后一个错误值。
答案 1 :(得分:1)
解决方案是第二次拨打电话。
以下是实际运行的控制台应用程序的代码:
// GetComputerName.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <string> // for string
#include <vector> // for vector
using std::vector;
using std::string;
#ifdef _UNICODE
using std::wstring;
#define string wstring
using std::wostringstream;
#define ostringstream wostringstream
#else
#endif
typedef vector<TCHAR> VTChar; // vtc
CWinApp theApp; // The one and only application object
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
bool gotName(false);
TCHAR tcLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1]= {_T('\0')};
DWORD dwComputerNameLength(_countof(tcLocalComputerName));
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
dwComputerNameLength= _countof(tcLocalComputerName);
AfxMessageBox(_T("First GetComputerName failed."));
if(!::GetComputerName(tcLocalComputerName, &dwComputerNameLength))
{
DWORD dwLastError(::GetLastError());
string strErrorFormat(_T("GetComputerName failed with %d; returned length was %d."));
VTChar vtcError(strErrorFormat.size() + 20, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strErrorFormat.c_str(), dwLastError, dwComputerNameLength);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
else
gotName= true;
}
else
gotName= true;
if(gotName)
{
string strFormat(_T("GetComputerName returned \"%s\""));
VTChar vtcError(strFormat.size() + 30, 0);
_stprintf_s(&vtcError[0], vtcError.size(), strFormat.c_str(), tcLocalComputerName);
AfxMessageBox(&vtcError[0], MB_ICONEXCLAMATION);
}
return 0;
}
答案 2 :(得分:0)
这是错误的:
TCHAR tcLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1]= {_T('\0')};
DWORD dwComputerNameLength(MAX_COMPUTERNAME_LENGTH);
documentation for GetComputerName很清楚:
lpnSize [in,out]
在输入时,在TCHAR中指定缓冲区的大小。
所以正确的代码是
TCHAR tcLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1]= {_T('\0')};
DWORD dwComputerNameLength(MAX_COMPUTERNAME_LENGTH + 1);
甚至更好,
TCHAR tcLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1]= {_T('\0')};
DWORD dwComputerNameLength(_countof(tcLocalComputerName));