Hàm nào lấy thông số CPU hay thông số ổ đĩa hay thông số gì đó tương tự???

Liên hệ QC

quangthanhdu

Thành viên chính thức
Tham gia
21/5/10
Bài viết
51
Được thích
4
Mỗi máy tính sẽ có một thông số khác nhau( thông số gì cũng được miễn sao khi mang file excel qua máy tính khác thì sẽ cho một thông số khác), mọi người chỉ giúp em có công thức excel nào lấy ra thông số đó. @#!^%
 
Tại 1 ô nào đó bạn nhập thế này coi ra cái gì nhé

=cell("filename")
 
Lấy ID của CPU:
Mã:
Sub GetCPUID()
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
MsgBox "Processor Id: " & objItem.ProcessorId
Next
End Sub
Lấy serial number của ổ cứng:
Mã:
Option Explicit
Declare Function GetVolumeInformationA Lib "kernel32" _
(ByVal lpRootPathName As String, _
ByVal lpVolumeNameBuffer As String, _
ByVal nVolumeNameSize As Long, _
lpVolumeSerialNumber As Long, _
lpMaximumComponentLength As Long, _
lpFileSystemFlags As Long, _
ByVal lpFileSystemNameBuffer As String, _
ByVal nFileSystemNameSize As Long) As Long
Sub SeriesNumber()
Dim SerialNumber As Long
GetVolumeInformationA "C:\", vbNullString, 0, SerialNumber, _
0, 0, vbNullString, 0
MsgBox SerialNumber
End Sub
 
Lần chỉnh sửa cuối:
Lấy ID của CPU:
Mã:
Sub GetCPUID()
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
MsgBox "Processor Id: " & objItem.ProcessorId
Next
End Sub
Lấy serial number của ổ cứng:
Mã:
Option Explicit
Declare Function GetVolumeInformationA Lib "kernel32" _
(ByVal lpRootPathName As String, _
ByVal lpVolumeNameBuffer As String, _
ByVal nVolumeNameSize As Long, _
lpVolumeSerialNumber As Long, _
lpMaximumComponentLength As Long, _
lpFileSystemFlags As Long, _
ByVal lpFileSystemNameBuffer As String, _
ByVal nFileSystemNameSize As Long) As Long
Sub SeriesNumber()
Dim SerialNumber As Long
GetVolumeInformationA "C:\", vbNullString, 0, SerialNumber, _
0, 0, vbNullString, 0
MsgBox SerialNumber
End Sub
Trong DOS có lệnh WMIC rất hay. Gần như nó có thể lấy mọi thông tin liên quan đến máy tính
Ví dụ lấy CPU ID là: WMIC CPU get ProcessorID
"Nhúng" câu lệnh này vào VB ta sẽ viết thế này
PHP:
Function GetCPUID() As String
  Dim sComm As String, tmpFile, Arr
  On Error Resume Next
  With CreateObject("Scripting.FileSystemObject")
    tmpFile = .GetTempName
    sComm = "wmic CPU get ProcessorID" & " > " & tmpFile
    CreateObject("Wscript.Shell").Run "cmd /c " & sComm, 0, True
    Arr = Split(.OpenTextFile(tmpFile, 1, 0, -1).ReadAll, vbCrLf)
  End With
  GetCPUID = Arr(1)
  Kill tmpFile
End Function
vân vân và vân vân
Cứ thí nghiệm bằng cách gõ vào cửa sổ CMD lệnh: WMIC /? sẽ phát hiện rất nhiều thứ thú vị
 
Lấy ID của CPU:
Mã:
Sub GetCPUID()
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
MsgBox "Processor Id: " & objItem.ProcessorId
Next
End Sub
Lấy serial number của ổ cứng:
Mã:
Option Explicit
Declare Function GetVolumeInformationA Lib "kernel32" _
(ByVal lpRootPathName As String, _
ByVal lpVolumeNameBuffer As String, _
ByVal nVolumeNameSize As Long, _
lpVolumeSerialNumber As Long, _
lpMaximumComponentLength As Long, _
lpFileSystemFlags As Long, _
ByVal lpFileSystemNameBuffer As String, _
ByVal nFileSystemNameSize As Long) As Long
Sub SeriesNumber()
Dim SerialNumber As Long
GetVolumeInformationA "C:\", vbNullString, 0, SerialNumber, _
0, 0, vbNullString, 0
MsgBox SerialNumber
End Sub

Cái trên đâu có phải trả về thông số của đĩa cứng vật lý???.
Thứ nhất: ngay tên hàm API cho thấy là nó đọc thông số của partition / logical disk / phân vùng.
Thứ hai: nhìn cái "C:\" là biết nó đọc serial number của partition C
Bạn mua 1 đĩa cứng ở cửa hàng về. Cái đĩa vật lý này chỉ có 1. Nhưng bạn có thể chia nó thành vd. 3 "đĩa" / phân vùng / partition C, D, E. Bạn gọi hàm trên cho "C:\", "D:\", "E:\" thì sẽ có 3 số khác nhau. Vậy số nào là số của cái đĩa vật lý kia đây??? Một chút tư duy đủ thấy được vấn đề.
Cái nữa là nếu bạn Format C, D, E thì bạn sẽ đọc ra những số khác.
Kết luận: Hàm trên chỉ đọc serial number của phân vùng, mà số này cũng thay đổi khi Format phân vùng. Cái số của nhà sản xuất ghi trên đĩa vật lý và có nêu trong bảo hành đâu có đọc được bằng cái hàm kia.
 
Cái trên đâu có phải trả về thông số của đĩa cứng vật lý???.
Thứ nhất: ngay tên hàm API cho thấy là nó đọc thông số của partition / logical disk / phân vùng.
Thứ hai: nhìn cái "C:\" là biết nó đọc serial number của partition C
Bạn mua 1 đĩa cứng ở cửa hàng về. Cái đĩa vật lý này chỉ có 1. Nhưng bạn có thể chia nó thành vd. 3 "đĩa" / phân vùng / partition C, D, E. Bạn gọi hàm trên cho "C:\", "D:\", "E:\" thì sẽ có 3 số khác nhau. Vậy số nào là số của cái đĩa vật lý kia đây??? Một chút tư duy đủ thấy được vấn đề.
Cái nữa là nếu bạn Format C, D, E thì bạn sẽ đọc ra những số khác.
Kết luận: Hàm trên chỉ đọc serial number của phân vùng, mà số này cũng thay đổi khi Format phân vùng. Cái số của nhà sản xuất ghi trên đĩa vật lý và có nêu trong bảo hành đâu có đọc được bằng cái hàm kia.
Tôi thật sự cũng không biết Hard Disk Serial Number là cái gì nữa
Bạn cho hỏi dòng lệnh này: WMIC DiskDrive Get Signature liệu có phải là Serial Number không?
 
Tôi thật sự cũng không biết Hard Disk Serial Number là cái gì nữa
Bạn cho hỏi dòng lệnh này: WMIC DiskDrive Get Signature liệu có phải là Serial Number không?

Tôi cũng không rõ nữa. Cái thời tôi cũng tò mò thì chưa có WMIC. WMIC có trong Win 7, không có trong XP. Tôi dùng XP. Thời xưa, tôi còn nhớ, tôi có 1 code trong Delphi. Cũng chỉ là tò mò thôi chứ chả quan tâm đến những trò này. Chắc chắn tìm trên mạng sẽ có nhiều giải pháp.
Ý tôi muốn nói là phải đọc được serial của nhà sx chứ serial partition thì thay đổi được mà, đâu có là unique
Nói chung tôi không thích những trò này. Anh bán cho người ta phần mềm rồi anh chỉ cho chạy khi có số ở đĩa như thế này? Thế nếu tôi thay đĩa vì đĩa cũ nhỏ, hỏng thì sao? Gọi điện, viết thư đăng ký lại? Thế nếu anh phá sản làm việc khác thì tôi chào tạm biệt phần mềm tôi bỏ tiền ra mua?
 
Lần chỉnh sửa cuối:
WMIC có trong Win 7, không có trong XP. Tôi dùng XP.
Ủa kỳ vậy ta? Tôi thử dùng WMIC trên máy của thằng bạn (WinXP) vẫn chạy được mà bạn
Có điều khi gõ WMIC /? xong, nó hiện ra 1 thông báo đại khái bảo "vui lòng đợi, đang install.. cái gì đó" ---> Xong, chạy bình thường
Hỏi thêm: Liệu code dưới đây có phải là lấy HDD Serial number khộng?
PHP:
Function GetDiskSN() As String
  Dim tmp, objItem As Object
  'On Error Resume Next
  With GetObject("winmgmts:\\.\root\cimv2")
    For Each objItem In .ExecQuery("SELECT * FROM Win32_PhysicalMedia")
      tmp = objItem.SerialNumber
      If TypeName(tmp) = "String" Then
        If Len(tmp) > 1 Then
          GetDiskSN = Trim(tmp)
          Exit Function
        End If
      End If
    Next
  End With
End Function
Nói chung chỉ là nghiên cứu chơi thôi cứ tôi cũng không thích trò này (vì biết chắc người ta dùng để tạo "phần mềm dùng thử" gì đó trên Excel...)
 
Ủa kỳ vậy ta? Tôi thử dùng WMIC trên máy của thằng bạn (WinXP) vẫn chạy được mà bạn
Có điều khi gõ WMIC /? xong, nó hiện ra 1 thông báo đại khái bảo "vui lòng đợi, đang install.. cái gì đó" ---> Xong, chạy bình thường
Hỏi thêm: Liệu code dưới đây có phải là lấy HDD Serial number khộng?
PHP:
........................................
Nói chung chỉ là nghiên cứu chơi thôi cứ tôi cũng không thích trò này (vì biết chắc người ta dùng để tạo "phần mềm dùng thử" gì đó trên Excel...)[/QUOTE]

Máy mình dùng Wind XP chép code trên vào Test là được ngay.
 
Ủa kỳ vậy ta? Tôi thử dùng WMIC trên máy của thằng bạn (WinXP) vẫn chạy được mà bạn
Có điều khi gõ WMIC /? xong, nó hiện ra 1 thông báo đại khái bảo "vui lòng đợi, đang install.. cái gì đó" ---> Xong, chạy bình thường
Hỏi thêm: Liệu code dưới đây có phải là lấy HDD Serial number khộng?
PHP:
Function GetDiskSN() As String
  Dim tmp, objItem As Object
  'On Error Resume Next
  With GetObject("winmgmts:\\.\root\cimv2")
    For Each objItem In .ExecQuery("SELECT * FROM Win32_PhysicalMedia")
      tmp = objItem.SerialNumber
      If TypeName(tmp) = "String" Then
        If Len(tmp) > 1 Then
          GetDiskSN = Trim(tmp)
          Exit Function
        End If
      End If
    Next
  End With
End Function
Nói chung chỉ là nghiên cứu chơi thôi cứ tôi cũng không thích trò này (vì biết chắc người ta dùng để tạo "phần mềm dùng thử" gì đó trên Excel...)

Rất có thể WMIC có trong XP professional, tôi dùng Home không thấy.
Tôi cũng không rõ là code trên có thực sự đọc được serial của nhà sản xuất không. Để biết chắc chắn 100 % thì chỉ còn nước là khi mua đĩa thì ghi serial rồi sau đó đọc bằng code xem thế nào. Hoặc phải "lục kỹ" internet. Lục kỹ bởi đầy rẫy những code kiểu "GetVolumeInformation".
Có thời tôi tò mò về WMI. Tò mò và tìm hiểu chút về bản thân WMI chứ không phải tò mò là nó đọc disk serial như thế nào. Bởi thực ra rất nhiều thông tin có thể đọc trực tiếp từ system, từ registry. Chẳng hạn dùng method của WMI có thể tắt máy, nhưng dùng nó làm gì khi có thể làm đơn giản hơn. Có thể dùng method của WMI để khởi động notepad chẳng hạn nhưng dùng làm gì khi mà có thể làm đơn giản hơn. Trong code có thể gọi hàm của system để làm những chuyện vd. như trên.
----------------
To sealand:
code "winmgmts:\\.\root\cimv2" chạy được thì đúng rồi. Nó dùng WMI (Windows Management Instrumentation) để đọc thông tin. WMI thì có trong Windows từ lâu rồi, tôi cũng có. Cái tôi không có là WMIC (Windows Management Instrumentation Command-line). Khi viết trong cửa sổ dòng lệnh wmic /? thì cũng chỉ được báo là "Tên "wmic" không là lệnh, phần mềm thực thi, ..." Cũng chả có: "Ông có muốn cài ...?" để mà "ừ". Do tôi có XP chỉ Home chăng? Tôi cũng không tìm hiểu thêm vì chả quan tâm.
---------------
Ở dưới tôi đính kèm ví dụ dùng WMI trong Delphi cho ai tò mò. Có WMI.exe để kích hoạt luôn và chọn trong combobox mục cần đọc thông tin. Có cả source code cho ai có Delphi mà sợ tôi cài virút.
 

File đính kèm

  • WMI.rar
    174.8 KB · Đọc: 159
Lần chỉnh sửa cuối:
Nói chung chỉ là nghiên cứu chơi thôi cứ tôi cũng không thích trò này (vì biết chắc người ta dùng để tạo "phần mềm dùng thử" gì đó trên Excel...)
-Mình nghĩ diễn đàn ta nên hỗ trợ và khuyến khích việc dùng excel để viết phần mềm thương mại. Bản thân việc này xét cho cùng vẫn có lợi cho việc học tập, nghiên cứu và không đi ngược với tôn chỉ của GPE.
Nguyên văn bởi siwtom
Nói chung tôi không thích những trò này. Anh bán cho người ta phần mềm rồi anh chỉ cho chạy khi có số ở đĩa như thế này? Thế nếu tôi thay đĩa vì đĩa cũ nhỏ, hỏng thì sao? Gọi điện, viết thư đăng ký lại? Thế nếu anh phá sản làm việc khác thì tôi chào tạm biệt phần mềm tôi bỏ tiền ra mua?
Cám ơn bạn đã cho biết những bất lợi của việc dùng S/N của phân vùng thay vì S/N ổ đĩa của nhà sản xuất. Nên vấn đề là làm sao tìm cho được S/N của ổ đĩa.
Đoạn code sau ( sưu tầm) lấy được chính xác Model và S/N của tất cả ổ cứng trong máy.
Mã:
Option Explicit
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const OPEN_EXISTING = 3
Private Const CREATE_NEW = 1
Private Const INVALID_HANDLE_VALUE = -1
Private Const VER_PLATFORM_WIN32_NT = 2
Private Const IDENTIFY_BUFFER_SIZE = 512
Private Const OUTPUT_DATA_SIZE = IDENTIFY_BUFFER_SIZE + 16
'GETVERSIONOUTPARAMS contains the data returned
'from the Get Driver Version function
Private Type GETVERSIONOUTPARAMS
   bVersion       As Byte 'Binary driver version.
   bRevision      As Byte 'Binary driver revision
   bReserved      As Byte 'Not used
   bIDEDeviceMap  As Byte 'Bit map of IDE devices
   fCapabilities  As Long 'Bit mask of driver capabilities
   dwReserved(3)  As Long 'For future use
End Type
'IDE registers
Private Type IDEREGS
   bFeaturesReg     As Byte 'Used for specifying SMART "commands"
   bSectorCountReg  As Byte 'IDE sector count register
   bSectorNumberReg As Byte 'IDE sector number register
   bCylLowReg       As Byte 'IDE low order cylinder value
   bCylHighReg      As Byte 'IDE high order cylinder value
   bDriveHeadReg    As Byte 'IDE drive/head register
   bCommandReg      As Byte 'Actual IDE command
   bReserved        As Byte 'reserved for future use - must be zero
End Type
'SENDCMDINPARAMS contains the input parameters for the
'Send Command to Drive function
Private Type SENDCMDINPARAMS
   cBufferSize     As Long     'Buffer size in bytes
   irDriveRegs     As IDEREGS  'Structure with drive register values.
   bDriveNumber    As Byte     'Physical drive number to send command to (0,1,2,3).
   bReserved(2)    As Byte     'Bytes reserved
   dwReserved(3)   As Long     'DWORDS reserved
   bBuffer()      As Byte      'Input buffer.
End Type
'Valid values for the bCommandReg member of IDEREGS.
Private Const IDE_ID_FUNCTION = &HEC            'Returns ID sector for ATA.
Private Const IDE_EXECUTE_SMART_FUNCTION = &HB0 'Performs SMART cmd.
                                                'Requires valid bFeaturesReg,
                                                'bCylLowReg, and bCylHighReg
 
'Cylinder register values required when issuing SMART command
Private Const SMART_CYL_LOW = &H4F
Private Const SMART_CYL_HI = &HC2
'Status returned from driver
Private Type DRIVERSTATUS
   bDriverError  As Byte          'Error code from driver, or 0 if no error
   bIDEStatus    As Byte          'Contents of IDE Error register
                                  'Only valid when bDriverError is SMART_IDE_ERROR
   bReserved(1)  As Byte
   dwReserved(1) As Long
 End Type
Private Type IDSECTOR
   wGenConfig                 As Integer
   wNumCyls                   As Integer
   wReserved                  As Integer
   wNumHeads                  As Integer
   wBytesPerTrack             As Integer
   wBytesPerSector            As Integer
   wSectorsPerTrack           As Integer
   wVendorUnique(2)           As Integer
   sSerialNumber(19)          As Byte
   wBufferType                As Integer
   wBufferSize                As Integer
   wECCSize                   As Integer
   sFirmwareRev(7)            As Byte
   sModelNumber(39)           As Byte
   wMoreVendorUnique          As Integer
   wDoubleWordIO              As Integer
   wCapabilities              As Integer
   wReserved1                 As Integer
   wPIOTiming                 As Integer
   wDMATiming                 As Integer
   wBS                        As Integer
   wNumCurrentCyls            As Integer
   wNumCurrentHeads           As Integer
   wNumCurrentSectorsPerTrack As Integer
   ulCurrentSectorCapacity    As Long
   wMultSectorStuff           As Integer
   ulTotalAddressableSectors  As Long
   wSingleWordDMA             As Integer
   wMultiWordDMA              As Integer
   bReserved(127)             As Byte
End Type
 
'Structure returned by SMART IOCTL commands
Private Type SENDCMDOUTPARAMS
  cBufferSize   As Long         'Size of Buffer in bytes
  DRIVERSTATUS  As DRIVERSTATUS 'Driver status structure
  bBuffer()    As Byte          'Buffer of arbitrary length for data read from drive
End Type
 
'Vendor specific feature register defines
'for SMART "sub commands"
Private Const SMART_ENABLE_SMART_OPERATIONS = &HD8
 
'Status Flags Values
Public Enum STATUS_FLAGS
   PRE_FAILURE_WARRANTY = &H1
   ON_LINE_COLLECTION = &H2
   PERFORMANCE_ATTRIBUTE = &H4
   ERROR_RATE_ATTRIBUTE = &H8
   EVENT_COUNT_ATTRIBUTE = &H10
   SELF_PRESERVING_ATTRIBUTE = &H20
End Enum
 
'IOCTL commands
Private Const DFP_GET_VERSION = &H74080
Private Const DFP_SEND_DRIVE_COMMAND = &H7C084
Private Const DFP_RECEIVE_DRIVE_DATA = &H7C088
 
Private Type ATTR_DATA
   AttrID As Byte
   AttrName As String
   AttrValue As Byte
   ThresholdValue As Byte
   WorstValue As Byte
   StatusFlags As STATUS_FLAGS
End Type
Private Type DRIVE_INFO
   bDriveType As Byte
   SerialNumber As String
   Model As String
   FirmWare As String
   Cilinders As Long
   Heads As Long
   SecPerTrack As Long
   BytesPerSector As Long
   BytesperTrack As Long
   NumAttributes As Byte
   Attributes() As ATTR_DATA
End Type
Private Enum IDE_DRIVE_NUMBER
   PRIMARY_MASTER
   PRIMARY_SLAVE
   SECONDARY_MASTER
   SECONDARY_SLAVE
   TERTIARY_MASTER
   TERTIARY_SLAVE
   QUARTIARY_MASTER
   QUARTIARY_SLAVE
End Enum
Private Declare Function CreateFile Lib "kernel32" _
   Alias "CreateFileA" _
  (ByVal lpFileName As String, _
   ByVal dwDesiredAccess As Long, _
   ByVal dwShareMode As Long, _
   lpSecurityAttributes As Any, _
   ByVal dwCreationDisposition As Long, _
   ByVal dwFlagsAndAttributes As Long, _
   ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
  (ByVal hObject As Long) As Long
  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, _
   lpOverlapped As Any) As Long
  Private Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (hpvDest As Any, _
   hpvSource As Any, _
   ByVal cbCopy As Long)
  Private Type OSVERSIONINFO
   OSVSize As Long
   dwVerMajor As Long
   dwVerMinor As Long
   dwBuildNumber As Long
   PlatformID As Long
   szCSDVersion As String * 128
End Type
Private Declare Function GetVersionEx Lib "kernel32" _
   Alias "GetVersionExA" _
  (LpVersionInformation As OSVERSIONINFO) As Long
Private Sub Command1_Click()
Dim di As DRIVE_INFO
   Dim drvNumber As Long
   For drvNumber = PRIMARY_MASTER To QUARTIARY_SLAVE
   di = GetDriveInfo(drvNumber)
      List1.AddItem "Drive " & drvNumber
       With di
      Select Case .bDriveType
            Case 0
               List1.AddItem vbTab & "[Not present]"
            Case 1
               List1.AddItem vbTab & "Model:" & vbTab & Trim$(.Model)
               List1.AddItem vbTab & "Serial No:" & vbTab & Trim$(.SerialNumber)
            Case 2
               List1.AddItem vbTab & "[ATAPI drive - info not available]"
            Case Else
               List1.AddItem vbTab & "[drive type not known]"
         End Select
          End With
      Next
   End Sub
Private Function GetDriveInfo(drvNumber As IDE_DRIVE_NUMBER) As DRIVE_INFO
    Dim hDrive As Long
   Dim di As DRIVE_INFO
   hDrive = SmartOpen(drvNumber)
   If hDrive <> INVALID_HANDLE_VALUE Then
   If SmartGetVersion(hDrive) = True Then
      With di
            .bDriveType = 0
            .NumAttributes = 0
            ReDim .Attributes(0)
            .bDriveType = 1
         End With
         If SmartCheckEnabled(hDrive, drvNumber) Then
            If IdentifyDrive(hDrive, IDE_ID_FUNCTION, drvNumber, di) = True Then
         GetDriveInfo = di
               End If   'IdentifyDrive
         End If   'SmartCheckEnabled
      End If   'SmartGetVersion
   End If   'hDrive <> INVALID_HANDLE_VALUE
    CloseHandle hDrive
   End Function
Private Function IdentifyDrive(ByVal hDrive As Long, _
                               ByVal IDCmd As Byte, _
                               ByVal drvNumber As IDE_DRIVE_NUMBER, _
                               di As DRIVE_INFO) As Boolean
    
  'Function: Send an IDENTIFY command to the drive
  'drvNumber = 0-3
  'IDCmd = IDE_ID_FUNCTION or IDE_ATAPI_ID
   Dim SCIP As SENDCMDINPARAMS
   Dim IDSEC As IDSECTOR
   Dim bArrOut(OUTPUT_DATA_SIZE - 1) As Byte
   Dim cbBytesReturned As Long
   With SCIP
      .cBufferSize = IDENTIFY_BUFFER_SIZE
      .bDriveNumber = CByte(drvNumber)
         With .irDriveRegs
         .bFeaturesReg = 0
         .bSectorCountReg = 1
         .bSectorNumberReg = 1
         .bCylLowReg = 0
         .bCylHighReg = 0
         .bDriveHeadReg = &HA0 'compute the drive number
         If Not IsWinNT4Plus Then
            .bDriveHeadReg = .bDriveHeadReg Or ((drvNumber And 1) * 16)
         End If
         'the command can either be IDE
         'identify or ATAPI identify.
         .bCommandReg = CByte(IDCmd)
      End With
   End With
    If DeviceIoControl(hDrive, _
                      DFP_RECEIVE_DRIVE_DATA, _
                      SCIP, _
                      Len(SCIP) - 4, _
                      bArrOut(0), _
                      OUTPUT_DATA_SIZE, _
                      cbBytesReturned, _
                      ByVal 0&) Then
                      
      CopyMemory IDSEC, bArrOut(16), Len(IDSEC)
 
      di.Model = StrConv(SwapBytes(IDSEC.sModelNumber), vbUnicode)
      di.SerialNumber = StrConv(SwapBytes(IDSEC.sSerialNumber), vbUnicode)
       IdentifyDrive = True
      End If
    End Function
Private Function IsWinNT4Plus() As Boolean
'returns True if running Windows NT4 or later
   Dim osv As OSVERSIONINFO
 osv.OSVSize = Len(osv)
If GetVersionEx(osv) = 1 Then
   IsWinNT4Plus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                     (osv.dwVerMajor >= 4)
 
   End If
End Function
Private Function SmartCheckEnabled(ByVal hDrive As Long, _
                                   drvNumber As IDE_DRIVE_NUMBER) As Boolean
   'SmartCheckEnabled - Check if SMART enable
  'FUNCTION: Send a SMART_ENABLE_SMART_OPERATIONS command to the drive
  'bDriveNum = 0-3
   Dim SCIP As SENDCMDINPARAMS
   Dim SCOP As SENDCMDOUTPARAMS
   Dim cbBytesReturned As Long
   With SCIP
   .cBufferSize = 0
      With .irDriveRegs
           .bFeaturesReg = SMART_ENABLE_SMART_OPERATIONS
           .bSectorCountReg = 1
           .bSectorNumberReg = 1
           .bCylLowReg = SMART_CYL_LOW
           .bCylHighReg = SMART_CYL_HI
            .bDriveHeadReg = &HA0
            If Not IsWinNT4Plus Then
               .bDriveHeadReg = .bDriveHeadReg Or ((drvNumber And 1) * 16)
            End If
           .bCommandReg = IDE_EXECUTE_SMART_FUNCTION
           End With
       .bDriveNumber = drvNumber
       End With
   SmartCheckEnabled = DeviceIoControl(hDrive, _
                                      DFP_SEND_DRIVE_COMMAND, _
                                      SCIP, _
                                      Len(SCIP) - 4, _
                                      SCOP, _
                                      Len(SCOP) - 4, _
                                      cbBytesReturned, _
                                      ByVal 0&)
End Function
Private Function SmartGetVersion(ByVal hDrive As Long) As Boolean
   Dim cbBytesReturned As Long
   Dim GVOP As GETVERSIONOUTPARAMS
   SmartGetVersion = DeviceIoControl(hDrive, _
                                     DFP_GET_VERSION, _
                                     ByVal 0&, 0, _
                                     GVOP, _
                                     Len(GVOP), _
                                     cbBytesReturned, _
                                     ByVal 0&)
   End Function
Private Function SmartOpen(drvNumber As IDE_DRIVE_NUMBER) As Long
'Open SMART to allow DeviceIoControl
  'communications and return SMART handle
If IsWinNT4Plus() Then
      SmartOpen = CreateFile("[URL="file://\\.\PhysicalDrive"]\\.\PhysicalDrive[/URL]" & CStr(drvNumber), _
                             GENERIC_READ Or GENERIC_WRITE, _
                             FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                             ByVal 0&, _
                             OPEN_EXISTING, _
                             0&, _
                             0&)
 
   Else
      SmartOpen = CreateFile("[URL="file://\\.\SMARTVSD"]\\.\SMARTVSD[/URL]", _
                              0&, 0&, _
                              ByVal 0&, _
                              CREATE_NEW, _
                              0&, _
                              0&)
   End If
   End Function
Private Function SwapBytes(b() As Byte) As Byte()
   'Note: VB4-32 and VB5 do not support the
  'return of arrays from a function. For
  'developers using these VB versions there
  'are two workarounds to this restriction:
  '
  '1) Change the return data type ( As Byte() )
  '   to As Variant (no brackets). No change
  '   to the calling code is required.
  '
  '2) Change the function to a sub, remove
  '   the last line of code (SwapBytes = b()),
  '   and take advantage of the fact the
  '   original byte array is being passed
  '   to the function ByRef, therefore any
  '   changes made to the passed data are
  '   actually being made to the original data.
  '   With this workaround the calling code
  '   also requires modification:
  '
  '      di.Model = StrConv(SwapBytes(IDSEC.sModelNumber), vbUnicode)
  '
  '   ... to ...
  '
  '      Call SwapBytes(IDSEC.sModelNumber)
  '      di.Model = StrConv(IDSEC.sModelNumber, vbUnicode)
    Dim bTemp As Byte
   Dim cnt As Long
For cnt = LBound(b) To UBound(b) Step 2
      bTemp = b(cnt)
      b(cnt) = b(cnt + 1)
      b(cnt + 1) = bTemp
   Next cnt
      SwapBytes = b()
      End Function
 

File đính kèm

  • GetDriveInFo.rar
    24.8 KB · Đọc: 173
-Mình nghĩ diễn đàn ta nên hỗ trợ và khuyến khích việc dùng excel để viết phần mềm thương mại. Bản thân việc này xét cho cùng vẫn có lợi cho việc học tập, nghiên cứu và không đi ngược với tôn chỉ của GPE.
Thì cái chuyện 1 người thích cái này và không thích cái khác là quan điểm của từng người, đâu có liên quan gì đến tôn chỉ của GPE
Các bạn thắc mắc vẫn có người trả lời đấy thôi
Cám ơn bạn đã cho biết những bất lợi của việc dùng S/N của phân vùng thay vì S/N ổ đĩa của nhà sản xuất. Nên vấn đề là làm sao tìm cho được S/N của ổ đĩa.
Đoạn code sau ( sưu tầm) lấy được chính xác Model và S/N của tất cả ổ cứng trong máy.
Thấy kết quả code của bạn cũng y chang với kết quả khi dùng code ở bài 8 ---> Bạn test thử xem
 
-
Cám ơn bạn đã cho biết những bất lợi của việc dùng S/N của phân vùng thay vì S/N ổ đĩa của nhà sản xuất. Nên vấn đề là làm sao tìm cho được S/N của ổ đĩa.
Đoạn code sau ( sưu tầm) lấy được chính xác Model và S/N của tất cả ổ cứng trong máy
Hồi xưa tôi tìm được code trong Delphi đọc serial trong các hđh kể cả 9x. Code đó đọc đĩa của tôi ra kết quả:
PHP:
Primary Controller - Master drive
Drive Model Number              : SAMSUNG SV0412H                         
Drive Serial Number             : 0536J1FT927540      
Drive Controller Revision Number: SK100-21
Controller Buffer Size on Drive : 2097152 bytes
Drive Type: Fixed
Physical Geometry: 16383 Cylinders, 16 Heads, 63 Sectors per track
Code của bạn trông giống giống về hướng đi. Đĩa của tôi nó đọc là:
PHP:
Model: SAMSUNG SV0412H
Serial No: 0536J1FT927540
Như thế code trong Delphi của tôi (ai cần thì cứ "gõ" cửa) và của bạn cho kết quả như nhau. Vậy có vẻ đáng tin.
Tôi cũng biết thế thôi. Chắc chắn 100 % thì phải đợi lúc có dịp so sánh với số của nhà sx.
 
Thì cái chuyện 1 người thích cái này và không thích cái khác là quan điểm của từng người, đâu có liên quan gì đến tôn chỉ của GPE
Các bạn thắc mắc vẫn có người trả lời đấy thôi

Thấy kết quả code của bạn cũng y chang với kết quả khi dùng code ở bài 8 ---> Bạn test thử xem

Đúng là cái code ngắn gọn của bạn nó cho ra cùng kết quả. Cũng cùng với kết quả mà code Delphi tôi tìm được hồi xưa trả về. Như thế chắc chắn là 90 %. Tôi sẽ có 100 % chắc chắn khi có dịp so sánh nó với số của nhà sản xuất.
 
Đúng là cái code ngắn gọn của bạn nó cho ra cùng kết quả. Cũng cùng với kết quả mà code Delphi tôi tìm được hồi xưa trả về. Như thế chắc chắn là 90 %. Tôi sẽ có 100 % chắc chắn khi có dịp so sánh nó với số của nhà sản xuất.
Trước khi post bài, mình đã tháo ổ cứng ra đối chiếu với kết quả trên. Như thế kết quả đó là chính xác 100%. Code của bạn ndu quả là ngắn gọn dù chưa lấy được model của ổ cứng. Không biết nếu máy có trên 1 ổ cứng thì nó lấy thông số của ổ nào?
 
Lần chỉnh sửa cuối:
Nếu mọi người thực sự muốn biết code của mình đáng tin cậy dùng cho các HĐH thì thử các tình huống test dưới đây nhé.

1. WinXP trở về trước - Cái này thường là lấy HDD SN không khó.
2. Win Vista, 7, 8 hay các phiên bản sau này. Chạy ở hai chế độ UAC ON và UAC OFF.
3. Nếu qua được bước 2 thì test trên Win 64-bit.
 
Trước khi post bài, mình đã tháo ổ cứng ra đối chiếu với kết quả trên. Như thế kết quả đó là chính xác 100%. Code của bạn ndu quả là ngắn gọn dù chưa lấy được model của ổ cứng. Không biết nếu máy có trên 1 ổ cứng thì nó lấy thông số của ổ nào?
Tiếc là tôi không có 2 ổ cứng gắn trong để thử, nhưng tôi tin chắc rằng code ấy cũng lấy được
Code là do tôi tự thí nghiệm mà ra ---> Quá trình duyệt qua vòng lập có khá nhiều "rác" nên tôi phải lọc để lấy cái cần lấy... lấy được rồi, tôi Exit Function luôn... Vậy nên tôi "đoán" nếu có trên 1 ổ cứng thì kết quả cũng sẽ được vòng lập "quét sạch" thôi
(đương nhiên khi ấy ta sẽ cho kết quả hàm vào 1 mảng)
Bạn tintam nếu có điều kiện hãy test thử xem (sửa code, đừng cho nó Exit Function)
(Hổng hiểu sao nghiên cứu lệnh WMIC trong DOS từ hôm qua đến giờ mà vẫn hổng biết cái nào là lấy HDD Serial Number... Hic... chắc tại mình ngu quá)
 
Vậy nên tôi "đoán" nếu có trên 1 ổ cứng thì kết quả cũng sẽ được vòng lập "quét sạch" thôi
(đương nhiên khi ấy ta sẽ cho kết quả hàm vào 1 mảng)
Mình đã test với 2 ổ cứng. Kết quả như bạn đã "đoán". Vòng lặp For Each objItem... duyệt và lấy S/N của cả 2 ổ cứng. Đoạn code thật ngắn gọn và hiệu quả. Tuy nhiên, có chỗ mình chưa hiểu lắm. Tại sao nó lặp 3 lần? Tại sao không ít hơn hoặc nhiều hơn?
 
Theo tôi thì không cần hàm gì cho phức tạp
Chỉ cần dùng các phần mềm có sẵn trong Win. Ví dụ như My Computer/Manage
 
Theo tôi thì không cần hàm gì cho phức tạp
Chỉ cần dùng các phần mềm có sẵn trong Win. Ví dụ như My Computer/Manage

Bạn nói cái gì vậy? Cái này là người ta viết chương trình trong VBA và trong chương trình sẽ có công đoạn cần lấy HDD SN ---> Vậy bạn bảo "tạm ngưng chương trình" rồi ra ngoài tự tìm bằng tay à?
Mà ngay cả tìm bằng tay thì tôi cũng không biết cách luôn... Bạn nói vào Computer/Manage gì gì đó.. Hổng ấy bạn mô tả cụ thể luôn đi cho anh em học hỏi
-----------------------
Mình đã test với 2 ổ cứng. Kết quả như bạn đã "đoán". Vòng lặp For Each objItem... duyệt và lấy S/N của cả 2 ổ cứng. Đoạn code thật ngắn gọn và hiệu quả. Tuy nhiên, có chỗ mình chưa hiểu lắm. Tại sao nó lặp 3 lần? Tại sao không ít hơn hoặc nhiều hơn?
Vọc chơi thôi chứ thú thật là tôi chưa hiểu hết về WMI đâu
 
Web KT
Back
Top Bottom