0

VolumeDetailsWindows システムのドライブ ラベルとそれぞれのボリューム シリアル番号を取得しようとしています。私は 1 時間試してみましたが、構文が間違っているコードを作成しました。現在、次のエラーが発生して います-これ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
4

2 に答える 2

1

少なくとも次の主な問題が見られます。

1)wchar_tは、UNICODE 用にコンパイルしているため、適切なタイプです。マクロを使用してジェネリックコードを記述しTCHARたり、バッファを明示的に宣言したりできますwchar_tが、それを行う必要があります。

2) に間違ったパスを渡しているため、そのエラーが発生しますGetVolumeInformation()(末尾のバックスラッシュが必要なため、A:になる必要がありますA:\)。

さらに、同じ結果を得るにはもう少し簡単な方法があることに注意してください。区切り文字列リストGetLogicalDriveStrings()を直接取得するために使用できます。NULLたとえば、これを使用して分割し(UNICODE を忘れないでください)、c_str()各エントリで使用します。

変更されたコードについての編集
: ドライブ パスがA:\\(エスケープされているA:\\\\) のはなぜですか? 末尾のバックスラッシュが1 つだけ必要なのでmydrives、次のように宣言する必要があります。

wchar_t mydrives[] = L"A:\\";

EDIT 2 : コードにさらにエラーがあるため、レビュー済みのバージョンを投稿します。変更したいことは他にもありますが、実際に機能しないものだけを指摘します。

  1. retVolSnoボリューム通し番号を読み取る機能。元のバージョンはほぼ正しかったのですが、修正したバージョンでは無駄な文字変換を行っています。あなたがしなければならなかったのは、wchar_tドライブ パスを受け入れることだけでした。

  2. グローバル変数mydrives。実際には、そのためにグローバル変数は必要ありません。である必要がwchar_tあり、パスの前後のスペースは役に立ちません。末尾のバックスラッシュが 1 つ必要です。文字値 ( ) をインクリメントする行は、++mydrives[0];それに応じて変更する必要があります (インデックス 1 ではなく 0)。

  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;
}
于 2014-04-16T12:23:12.950 に答える
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:\
于 2014-04-16T12:19:29.207 に答える