检索WINDOWS驱动器的VolumeDetails - 卡住'char []'到'LPCWSTR'转换

时间:2014-04-16 12:14:28

标签: windows winapi wchar-t lpcwstr

我正在尝试获取我的WINDOWS系统的VolumeDetails - 驱动器标签及其各自的卷序列号。我已经尝试了一个小时,并构建了一个在语法上出错的代码。目前我收到以下错误 - 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 个答案:

答案 0 :(得分:1)

我看到至少这些主要问题:

1)wchar_t是正确的类型,因为您正在为UNICODE编译,您可以使用TCHAR宏编写通用代码,或者将您的缓冲区显式声明为{ {1}}但那是做什么的。

2)您有错误,因为您将错误的路径传递给wchar_t(需要提示反斜杠,因此GetVolumeInformation()必须变为A:)。

此外请注意,您可以通过更轻松的方式获得相同的结果,您可以使用A:\直接获取GetLogicalDriveStrings()分隔的字符串列表。例如,使用this(不要忘记UNICODE)拆分它,并在每个条目中使用NULL

编辑关于修改后的代码:
为什么您的路径是c_str()(转义为A:\\)?只需一个尾随反斜杠,因此A:\\\\必须声明为:

mydrives

编辑2 :您的代码中存在更多错误,因此我会发布已审核的版本。我会改变更多的事情,但我会指出实际上没有做什么。

  1. 函数wchar_t mydrives[] = L"A:\\"; 读取卷序列号。原始版本几乎是正确的,在您的修改版本中,您执行无用的字符转换。你要做的只是接受一个retVolSno驱动路径。

  2. 全局变量wchar_t。你实际上并不需要任何全局变量。它必须是mydrives并且路径之前/之后的空格是无用的。需要一个尾随反斜杠。必须相应地更改增加字符值(wchar_t)的行(索引0而不是1)。

  3. 检查驱动器可用性。在++mydrives[0];之后您忘记了if(DriveMask & 1),然后您无法打印驱动器名称,但即使在不可用的驱动器上也会执行{(错误123)。这就是缩进很重要的原因......

  4. 您正在混合使用UNICODE / NOT UNICODE和C / C ++。我强烈建议你选择其中一个并保留它(C或C ++?UNICODE或NOT UNICODE?)。例如,您使用C函数GetVolumeInformation()来打印内容,并且您同时拥有printf()std::string个内容。

  5. 让我们将所有内容放在一起,以获得工作版。首先是给出驱动路径读取序列号的功能:

    wchar_t

    它与原始版本几乎相同,只是更改为使用UNICODE字符。然后主要功能循环可用的驱动器并打印出他们的序列号:

    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();
    }
    

答案 1 :(得分:0)

documentation开始,如果传递了驱动器号,则第一个参数应该是尾部斜杠。

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:\