Получение 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: в вашем коде больше ошибок, поэтому я выложу проверенную версию. Есть еще вещи, которые я бы изменил, но я укажу только то, что на самом деле не работает.

  1. функция retVolSno прочитать том серийный номер. Оригинальная версия была почти правильной, в вашей модифицированной версии вы выполняете бесполезное преобразование символов. То, что вам нужно было сделать, это просто принять wchar_t дорожка проезда.

  2. Глобальная переменная mydrives, Вам на самом деле не нужна никакая глобальная переменная для этого. Это должно быть wchar_t и пробел до / после пути бесполезен. Требуется один завершающий обратный слеш. Строка, в которой вы увеличиваете значение символа (++mydrives[0];) должны быть изменены соответственно (индекс 0 вместо 1).

  3. Проверьте наличие диска. После if(DriveMask & 1) ты забыл { тогда вы не будете печатать имя диска, но вы будете выполнять GetVolumeInformation() даже на недоступных дисках (ошибка 123). Вот почему отступ важен...

  4. Вы смешиваете 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:\
Другие вопросы по тегам