[英]Converting HDD Serial # VB6 code into VB.NET code
我從VC ++項目中獲取了一段很酷的代碼,該代碼無需使用WMI即可獲取硬盤驅動器的完整信息(因為WMI本身有問題),我請熟悉API函數的人嘗試轉換將此VB6代碼轉換為VB(或C#)。NET,並幫助很多急需此實用工具類的人。 我花了很多時間,搜索了整個網絡,以找到獲取實際型號和HDD序列號的方法,如果只有.NET,最終找到了它。問題,只需將其粘貼到VB6 IDE中即可:
Option Explicit
''// Antonio Giuliana, 2001-2003
''// Costanti per l'individuazione della versione di OS
Private Const VER_PLATFORM_WIN32S = 0
Private Const VER_PLATFORM_WIN32_WINDOWS = 1
Private Const VER_PLATFORM_WIN32_NT = 2
''// Costanti per la comunicazione con il driver IDE
Private Const DFP_RECEIVE_DRIVE_DATA = &H7C088
''// Costanti per la CreateFile
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const OPEN_EXISTING = 3
Private Const CREATE_NEW = 1
''// Enumerazione dei comandi per la CmnGetHDData
Private Enum HDINFO
HD_MODEL_NUMBER
HD_SERIAL_NUMBER
HD_FIRMWARE_REVISION
End Enum
''// Struttura per l'individuazione della versione di OS
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
''// Struttura per il campo irDriveRegs della struttura SENDCMDINPARAMS
Private Type IDEREGS
bFeaturesReg As Byte
bSectorCountReg As Byte
bSectorNumberReg As Byte
bCylLowReg As Byte
bCylHighReg As Byte
bDriveHeadReg As Byte
bCommandReg As Byte
bReserved As Byte
End Type
''// Struttura per l'I/O dei comandi al driver IDE
Private Type SENDCMDINPARAMS
cBufferSize As Long
irDriveRegs As IDEREGS
bDriveNumber As Byte
bReserved(1 To 3) As Byte
dwReserved(1 To 4) As Long
End Type
''// Struttura per il campo DStatus della struttura SENDCMDOUTPARAMS
Private Type DRIVERSTATUS
bDriveError As Byte
bIDEStatus As Byte
bReserved(1 To 2) As Byte
dwReserved(1 To 2) As Long
End Type
''// Struttura per l'I/O dei comandi al driver IDE
Private Type SENDCMDOUTPARAMS
cBufferSize As Long
DStatus As DRIVERSTATUS ''// ovvero DriverStatus
bBuffer(1 To 512) As Byte
End Type
''// Per ottenere la versione del SO
Private Declare Function GetVersionEx _
Lib "kernel32" Alias "GetVersionExA" _
(lpVersionInformation As OSVERSIONINFO) As Long
''// Per ottenere un handle al device IDE
Private Declare Function CreateFile _
Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
''// Per chiudere l'handle del device IDE
Private Declare Function CloseHandle _
Lib "kernel32" _
(ByVal hObject As Long) As Long
''// Per comunicare con il driver IDE
Private Declare Function DeviceIoControl _
Lib "kernel32" _
(ByVal hDevice As Long, _
ByVal dwIoControlCode As Long, _
lpInBuffer As Any, _
ByVal nInBufferSize As Long, _
lpOutBuffer As Any, _
ByVal nOutBufferSize As Long, _
lpBytesReturned As Long, _
ByVal lpOverlapped As Long) As Long
''// Per azzerare buffer di scambio dati
Private Declare Sub ZeroMemory _
Lib "kernel32" Alias "RtlZeroMemory" _
(dest As Any, _
ByVal numBytes As Long)
''// Per copiare porzioni di memoria
Private Declare Sub CopyMemory _
Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
Private Declare Function GetLastError _
Lib "kernel32" () As Long
Private mvarCurrentDrive As Byte ''// Drive corrente
Private mvarPlatform As String ''// Piattaforma usata
Public Property Get Copyright() As String
''// Copyright
Copyright = "HDSN Vrs. 1.00, (C) Antonio Giuliana, 2001-2003"
End Property
''// Metodo GetModelNumber
Public Function GetModelNumber() As String
''// Ottiene il ModelNumber
GetModelNumber = CmnGetHDData(HD_MODEL_NUMBER)
End Function
''// Metodo GetSerialNumber
Public Function GetSerialNumber() As String
''// Ottiene il SerialNumber
GetSerialNumber = CmnGetHDData(HD_SERIAL_NUMBER)
End Function
''// Metodo GetFirmwareRevision
Public Function GetFirmwareRevision() As String
''// Ottiene la FirmwareRevision
GetFirmwareRevision = CmnGetHDData(HD_FIRMWARE_REVISION)
End Function
''// Proprieta' CurrentDrive
Public Property Let CurrentDrive(ByVal vData As Byte)
''// Controllo numero di drive fisico IDE
If vData < 0 Or vData > 3 Then
Err.Raise 10000, , "Illegal drive number" ''// IDE drive 0..3
End If
''// Nuovo drive da considerare
mvarCurrentDrive = vData
End Property
''// Proprieta' CurrentDrive
Public Property Get CurrentDrive() As Byte
''// Restituisce drive fisico corrente (IDE 0..3)
CurrentDrive = mvarCurrentDrive
End Property
''// Proprieta' Platform
Public Property Get Platform() As String
''// Restituisce tipo OS
Platform = mvarPlatform
End Property
Private Sub Class_Initialize()
''// Individuazione del tipo di OS
Dim OS As OSVERSIONINFO
OS.dwOSVersionInfoSize = Len(OS)
Call GetVersionEx(OS)
mvarPlatform = "Unk"
Select Case OS.dwPlatformId
Case Is = VER_PLATFORM_WIN32S
mvarPlatform = "32S" ''// Win32S
Case Is = VER_PLATFORM_WIN32_WINDOWS
If OS.dwMinorVersion = 0 Then
mvarPlatform = "W95" ''// Win 95
Else
mvarPlatform = "W98" ''// Win 98
End If
Case Is = VER_PLATFORM_WIN32_NT
mvarPlatform = "WNT" ''// Win NT/2000
End Select
End Sub
Private Function CmnGetHDData(hdi As HDINFO) As String
''// Rilevazione proprieta' IDE
Dim bin As SENDCMDINPARAMS
Dim bout As SENDCMDOUTPARAMS
Dim hdh As Long
Dim br As Long
Dim ix As Long
Dim hddfr As Long
Dim hddln As Long
Dim s As String
Select Case hdi ''// Selezione tipo caratteristica richiesta
Case HD_MODEL_NUMBER
hddfr = 55 ''// Posizione nel buffer del ModelNumber
hddln = 40 ''// Lunghezza nel buffer del ModelNumber
Case HD_SERIAL_NUMBER
hddfr = 21 ''// Posizione nel buffer del SerialNumber
hddln = 20 ''// Lunghezza nel buffer del SerialNumber
Case HD_FIRMWARE_REVISION
hddfr = 47 ''// Posizione nel buffer del FirmwareRevision
hddln = 8 ''// Lunghezza nel buffer del FirmwareRevision
Case Else
Err.Raise 10001, "Illegal HD Data type"
End Select
Select Case mvarPlatform
Case "WNT"
''// Per Win NT/2000 apertura handle al drive fisico
hdh = CreateFile("\\.\PhysicalDrive" & mvarCurrentDrive, _
GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, _
0, OPEN_EXISTING, 0, 0)
Case "W95", "W98"
''// Per Win 9X apertura handle al driver SMART
''// (in \WINDOWS\SYSTEM da spostare in \WINDOWS\SYSTEM\IOSUBSYS)
''// che comunica con il driver IDE
hdh = CreateFile("\\.\Smartvsd", _
0, 0, 0, CREATE_NEW, 0, 0)
Case Else
''// Piattaforma non supportata (Win32S)
Err.Raise 10002, , "Illegal platform (only WNT, W98 or W95)"
End Select
''// Controllo validità handle
If hdh = 0 Then
Err.Raise 10003, , "Error on CreateFile"
End If
''// Azzeramento strutture per l'I/O da driver
ZeroMemory bin, Len(bin)
ZeroMemory bout, Len(bout)
''// Preparazione parametri struttura di richiesta al driver
With bin
.bDriveNumber = mvarCurrentDrive
.cBufferSize = 512
With .irDriveRegs
If (mvarCurrentDrive And 1) Then
.bDriveHeadReg = &HB0
Else
.bDriveHeadReg = &HA0
End If
.bCommandReg = &HEC
.bSectorCountReg = 1
.bSectorNumberReg = 1
End With
End With
''// Richiesta al driver
DeviceIoControl hdh, DFP_RECEIVE_DRIVE_DATA, _
bin, Len(bin), bout, Len(bout), br, 0
''// Formazione stringa di risposta
''// da buffer di uscita
''// L'ordine dei byte e' invertito
s = ""
For ix = hddfr To hddfr + hddln - 1 Step 2
If bout.bBuffer(ix + 1) = 0 Then Exit For
s = s & Chr(bout.bBuffer(ix + 1))
If bout.bBuffer(ix) = 0 Then Exit For
s = s & Chr(bout.bBuffer(ix))
Next ix
''// Chiusura handle
CloseHandle hdh
''// Restituzione informazione richiesta
CmnGetHDData = Trim(s)
End Function
我找到了! 這是等效的VB.NET代碼。 它不完全是VB6代碼的轉換版本,但功能相同。 請享用!
Public Class HDDInfo
#Region " Declatrations "
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _
Private Shared Function CloseHandle(ByVal hObject As Integer) As Integer
End Function
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _
Private Shared Function DeviceIoControl(ByVal hDevice As Integer, ByVal dwIoControlCode As Integer, <[In](), Out()> ByVal lpInBuffer As SENDCMDINPARAMS, ByVal lpInBufferSize As Integer, <[In](), Out()> ByVal lpOutBuffer As SENDCMDOUTPARAMS, ByVal lpOutBufferSize As Integer, _
ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Integer
End Function
Private Const FILE_SHARE_READ As Short = &H1
Private Const FILE_SHARE_WRITE As Short = &H2
Private Const GENERIC_READ As Integer = &H80000000
Private Const GENERIC_WRITE As Integer = &H40000000
Private Const OPEN_EXISTING As Short = 3
Private Const CREATE_NEW As Short = 1
Private Const VER_PLATFORM_WIN32_NT As Integer = 2
Private Const DFP_RECEIVE_DRIVE_DATA As Integer = &H7C088
Private Const INVALID_HANDLE_VALUE As Integer = -1
#End Region
#Region " Classes "
<StructLayout(LayoutKind.Sequential, Size:=8)> _
Private Class IDEREGS
Public Features As Byte
Public SectorCount As Byte
Public SectorNumber As Byte
Public CylinderLow As Byte
Public CylinderHigh As Byte
Public DriveHead As Byte
Public Command As Byte
Public Reserved As Byte
End Class
<StructLayout(LayoutKind.Sequential, Size:=32)> _
Private Class SENDCMDINPARAMS
Public BufferSize As Integer
Public DriveRegs As IDEREGS
Public DriveNumber As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> _
Public Reserved As Byte()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public Reserved2 As Integer()
Public Sub New()
DriveRegs = New IDEREGS()
Reserved = New Byte(2) {}
Reserved2 = New Integer(3) {}
End Sub
End Class
<StructLayout(LayoutKind.Sequential, Size:=12)> _
Private Class DRIVERSTATUS
Public DriveError As Byte
Public IDEStatus As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public Reserved As Byte()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public Reserved2 As Integer()
Public Sub New()
Reserved = New Byte(1) {}
Reserved2 = New Integer(1) {}
End Sub
End Class
<StructLayout(LayoutKind.Sequential)> _
Private Class IDSECTOR
Public GenConfig As Short
Public NumberCylinders As Short
Public Reserved As Short
Public NumberHeads As Short
Public BytesPerTrack As Short
Public BytesPerSector As Short
Public SectorsPerTrack As Short
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> _
Public VendorUnique As Short()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> _
Public SerialNumber As Char()
Public BufferClass As Short
Public BufferSize As Short
Public ECCSize As Short
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> _
Public FirmwareRevision As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=40)> _
Public ModelNumber As Char()
Public MoreVendorUnique As Short
Public DoubleWordIO As Short
Public Capabilities As Short
Public Reserved1 As Short
Public PIOTiming As Short
Public DMATiming As Short
Public BS As Short
Public NumberCurrentCyls As Short
Public NumberCurrentHeads As Short
Public NumberCurrentSectorsPerTrack As Short
Public CurrentSectorCapacity As Integer
Public MultipleSectorCapacity As Short
Public MultipleSectorStuff As Short
Public TotalAddressableSectors As Integer
Public SingleWordDMA As Short
Public MultiWordDMA As Short
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=382)> _
Public Reserved2 As Byte()
End Class
<StructLayout(LayoutKind.Sequential)> _
Private Class SENDCMDOUTPARAMS
Public BufferSize As Integer
Public Status As DRIVERSTATUS
Public IDS As IDSECTOR
Public Sub New()
Status = New DRIVERSTATUS()
IDS = New IDSECTOR()
End Sub
End Class
#End Region
#Region " Methods and Functions "
Private Shared Function SwapChars(ByVal chars As Char()) As String
For i As Integer = 0 To chars.Length - 2 Step 2
Dim t As Char
t = chars(i)
chars(i) = chars(i + 1)
chars(i + 1) = t
Next
Dim s As New String(chars)
Return s
End Function
Public Shared Function GetHDDInfoString() As String
Dim serialNumber As String = " ", model As String = " ", firmware As String = " "
Dim handle As Integer, returnSize As Integer = 0
Dim driveNumber As Integer = 0
Dim sci As New SENDCMDINPARAMS()
Dim sco As New SENDCMDOUTPARAMS()
If Environment.OSVersion.Platform = PlatformID.Win32NT Then
handle = CreateFile("\\.\PhysicalDrive" & "0", GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
Else
handle = CreateFile("\\.\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0)
End If
If handle <> INVALID_HANDLE_VALUE Then
sci.DriveNumber = CByte(driveNumber)
sci.BufferSize = Marshal.SizeOf(sco)
sci.DriveRegs.DriveHead = CByte((&HA0 Or driveNumber << 4))
sci.DriveRegs.Command = &HEC
sci.DriveRegs.SectorCount = 1
sci.DriveRegs.SectorNumber = 1
If DeviceIoControl(handle, DFP_RECEIVE_DRIVE_DATA, sci, Marshal.SizeOf(sci), sco, Marshal.SizeOf(sco), _
returnSize, 0) <> 0 Then
serialNumber = SwapChars(sco.IDS.SerialNumber)
model = SwapChars(sco.IDS.ModelNumber)
firmware = SwapChars(sco.IDS.FirmwareRevision)
End If
CloseHandle(handle)
End If
Return model.Trim & " " & serialNumber.Trim
End Function
#End Region
End Class
抱歉,我沒有時間為您轉換它,但是如果沒有其他人提供代碼,那么比看看http://www.pinvoke.net可能要糟得多。 您的VB6代碼必須調用Windows API函數才能完成工作,而VB.NET代碼也必須執行相同操作。 它將調用相同的API函數。
例如, 這是DeviceIoControl的頁面。
但是,如果您等待了足夠長的時間,那么其他人可能只需要提交代碼:-)
Try
Dim Searcher_P As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_PhysicalMedia")
For Each queryObj As ManagementObject In Searcher_P.Get()
If queryObj("SerialNumber").ToString.Trim = "Y2S0RKFE" Then
Me.Cursor = Cursors.Default
Return True
End If
Next
Catch ex As Exception
MessageBox.Show("An error occurred while querying for WMI data: Win32_PhysicalMedia " & ex.Message)
End Try
Try
Dim Searcher_L As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_LogicalDisk WHERE DeviceID = 'C:'")
For Each queryObj As ManagementObject In Searcher_L.Get()
If queryObj("VolumeSerialNumber").ToString.Trim = "226C1A0B" Then
Me.Cursor = Cursors.Default
Return True
End If
Next
Catch ex As Exception
MessageBox.Show("An error occurred while querying for WMI data: VolumeSerialNumber " & ex.Message)
Return False
End Try
對於不理解評論中使用的口頭語言的人來說,這是很多代碼。
我會這樣說:在該代碼中的任何地方,您可能會看到要使用Structure
的Type
關鍵字,.Net中Properties的語法略有不同,函數調用需要括號,而VB.Net沒有'任何'類型(可能是System.IntPtr
而不是?)。
VB.Net中其余大多數語法都是相同的,因此您可能會很幸運地進行我已經提到的修復,然后解決分別構建最終代碼時遇到的每個錯誤(或錯誤類型)。
是的,我知道VB6,但問題出在API函數聲明以及將那些結構(類型)傳遞給它們所需的屬性。 那是我沒有時間花的地方! 如果您擁有自動的VB6到VB.NET工具以及VB6本身,請將代碼另存為VB6項目並進行代碼轉換。 我沒有VB6。
您可以獲取WMI的數據。 讓我舉一個例子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.