0

我正在尝试获取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;
}

我也试过用 替换charwchar_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
4

2 回答 2

1

至少看到以下主要问题:

1)wchar_t是正确的类型,因为您正在为 UNICODE 进行编译,您可以使用宏编写通用代码或显式声明您的缓冲区,但这就是要做的。TCHARwchar_t

2)你有这个错误,因为你传递了错误的路径GetVolumeInformation()(尾随反斜杠是必需的,所以A:必须成为A:\)。

此外请注意,您有更简单的方法来获得相同的结果,您可以使用GetLogicalDriveStrings()直接获取NULL分隔字符串列表。例如,使用this(不要忘记 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::stringwchar_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;
}
于 2014-04-16T12:23:12.950 回答
0

From the documentation , the first parameters should be with trailing slash if drive letter is passed.

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:\
于 2014-04-16T12:19:29.207 回答