Получение VolumeDetails дисков WINDOWS - застрявшее с преобразованием 'char []' в 'LPCWSTR'
Я пытаюсь получить VolumeDetails
моей системы WINDOWS - метка диска плюс соответствующий серийный номер тома. Я пробовал с часа и создал код, который не работает в синтаксисе. В настоящее время я получаю следующую ошибку: error C2664: 'GetVolumeInformationW' : cannot convert parameter 1 from 'char []' to 'LPCWSTR'
Вот мой код:
// getVolDrive.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <sstream>
#include <string>
#include <ctype.h>
#include <algorithm>
using namespace std;
//wchar_t mydrives[5];// = " A: ";
char mydrives[] = " A: ";
string retVolSno(char drives[]) //wchar_t drives[]
{
DWORD dwSerial;
stringstream ss;
cout<<drives<<endl;
if(!GetVolumeInformation(drives, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
{
ss<<"Error: "<<GetLastError();
}
else
{
ss<<hex<<dwSerial;
}
return ss.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
string cVolSno;
ULONG DriveMask = _getdrives();
if(DriveMask == 0)
printf("_getdrives() failed with failure code: %d\n", GetLastError());
else
{
printf("This machine has the following logical drives:\n");
while (DriveMask)
{
cout << "In While" << endl;
if(DriveMask & 1)
printf("%s", mydrives);
wcout << mydrives << endl;
cVolSno = retVolSno(mydrives);
cout<<cVolSno<<endl;
++mydrives[1];
DriveMask >>= 1;
}
}
//std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
//cout<<cVolSno<<endl;
_getch();
return 0;
}
Я также пытался заменить char
с wchar_t
Я не получил никаких ошибок сборки, но во время выполнения приложения получил Error Code 3- Path not found!
,
КОД ИЗМЕНЕН:
// getVolDrive.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <sstream>
#include <string>
#include <ctype.h>
#include <algorithm>
using namespace std;
//wchar_t mydrives[5];// = " A: ";
char mydrives[] = " A:\\\\ ";
string retVolSno(char drives[]) //wchar_t drives[]
{
DWORD dwSerial;
stringstream ss;
wchar_t text[10];
mbstowcs(text,drives,100); //strlen(drives)+1
LPWSTR ptr = text;
if(!GetVolumeInformation(ptr, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
{
ss<<"Error: "<<GetLastError();
}
else
{
ss<<hex<<dwSerial;
}
return ss.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
string cVolSno;
ULONG DriveMask = _getdrives();
if(DriveMask == 0)
printf("_getdrives() failed with failure code: %d\n", GetLastError());
else
{
printf("This machine has the following logical drives:\n");
while (DriveMask)
{
if(DriveMask & 1)
printf("%s \n", mydrives);
cVolSno = retVolSno(mydrives);
std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
cout<<cVolSno<<endl;
++mydrives[1];
DriveMask >>= 1;
}
}
//std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
//cout<<cVolSno<<endl;
_getch();
return 0;
}
ВЫХОД:
This machine has the following logical drives:
ERROR: 123
ERROR: 123
C:\\
ERROR: 123
D:\\
ERROR: 123
E:\\
ERROR: 123
2 ответа
Я вижу по крайней мере эти основные проблемы:
1) wchar_t
это правильный тип, потому что вы компилируете для UNICODE, вы можете написать общий код, используя TCHAR
макрос или явно объявить ваш буфер как wchar_t
но это то, что нужно сделать.
2) У вас есть эта ошибка, потому что вы передаете неправильный путь к GetVolumeInformation()
(конечный обратный слеш требуется так A:
должен стать A:\
).
Кроме того, обратите внимание, что у вас есть немного более простой способ достичь того же результата, вы можете использовать GetLogicalDriveStrings()
напрямую получить NULL
список строк с разделителями. Разделите его, используя, например, это (не забудьте UNICODE) и используйте c_str()
с каждой записью.
РЕДАКТИРОВАТЬ о своем измененном коде:
Почему вы едете путь A:\\
(сбежал в A:\\\\
)? Нужен только один завершающий обратный слеш mydrives
должен быть объявлен как:
wchar_t mydrives[] = L"A:\\";
РЕДАКТИРОВАТЬ 2: в вашем коде больше ошибок, поэтому я выложу проверенную версию. Есть еще вещи, которые я бы изменил, но я укажу только то, что на самом деле не работает.
функция
retVolSno
прочитать том серийный номер. Оригинальная версия была почти правильной, в вашей модифицированной версии вы выполняете бесполезное преобразование символов. То, что вам нужно было сделать, это просто принятьwchar_t
дорожка проезда.Глобальная переменная
mydrives
, Вам на самом деле не нужна никакая глобальная переменная для этого. Это должно бытьwchar_t
и пробел до / после пути бесполезен. Требуется один завершающий обратный слеш. Строка, в которой вы увеличиваете значение символа (++mydrives[0];
) должны быть изменены соответственно (индекс 0 вместо 1).Проверьте наличие диска. После
if(DriveMask & 1)
ты забыл{
тогда вы не будете печатать имя диска, но вы будете выполнятьGetVolumeInformation()
даже на недоступных дисках (ошибка 123). Вот почему отступ важен...Вы смешиваете UNICODE/NOT UNICODE и C/C++. Я настоятельно рекомендую вам выбрать один из них и оставить его (C или C++? UNICODE или NOT UNICODE?). Например, вы использовали функцию C
printf()
печатать вещи, и у вас есть обаstd::string
а такжеwchar_t
вещи.
Давайте соберем все вместе, чтобы получить рабочую версию. Сначала функция для чтения серийного номера по заданному пути привода:
wstring getVolumeSerialNumber(const wchar_t* drivePath)
{
DWORD dwSerial;
wstringstream ss;
if (!GetVolumeInformation(drivePath, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
ss << L"Error: " << GetLastError();
else
ss << hex << dwSerial;
return ss.str();
}
Это почти то же самое, что и ваша оригинальная версия, только что изменено для работы с символами UNICODE. Затем основная функция, которая перебирает доступные диски и распечатывает их серийный номер:
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t drive[] = L"A:\\";
ULONG driveMask = _getdrives();
if (driveMask == 0)
wcout << L"_getdrives() failed with failure code: " << GetLastError() << endl;
else
{
wcout << L"This machine has the following logical drives:" << endl;
while (driveMask)
{
if (driveMask & 1)
{
wcout << drive << endl;
wcout << getVolumeSerialNumber(drive) << endl;
}
++drive[0];
driveMask >>= 1;
}
}
wcin.ignore();
return 0;
}
Из документации первые параметры должны быть с косой чертой, если передается буква диска.
lpRootPathName [in, optional]
A pointer to a string that contains the root directory of the volume to be described.
If this parameter is NULL, the root of the current directory is used.
A trailing backslash is required.
For example, you specify \\MyServer\MyShare as \\MyServer\MyShare\, or the C drive as C:\