1. Luis Pesaressi
  2. PowerBuilder
  3. Wednesday, 10 February 2021 08:44 AM UTC

Hi, how can get the serial number of hard drive, I try with 

FUNCTION boolean GetVolumeInformationA(ref string lpRootPathName,ref string lpVolumeNameBuffer,ulong nVolumeNameSize,ref ulong lpVolumeSerialNumber,ref ulong lpMaximumComponentLength,ref ulong lpFileSystemFlags,ref string lpFileSystemNameBuffer,ulong nFileSystemNameSize) Library "kernel32.dll"

 

but not work  I have Windows 10 and 

 

thanks

 

Luis

René Ullrich Accepted Answer Pending Moderation
  1. Wednesday, 10 February 2021 09:01 AM UTC
  2. PowerBuilder
  3. # 1

How do you use GetVolumeInformation?

Maybe you have to use unicode function GetVolumeInformationW?

Have you seen this?

https://www.rgagnon.com/pbdetails/pb-0214.html

https://www.topwizprogramming.com/freecode_filesys.html

 

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 10 February 2021 15:01 PM UTC
  2. PowerBuilder
  3. # 2

Hi, Luis - 

I'm not sure why you are using the ANSI flavor of the GetVolumeInformation API function.

Setting that aside for the moment, if you are trying to obtain the manufacturer's serial number of the physical disk drive, the GetVolumeInformationA/W API function will probably not get you this info. From the online Windows documentation on the GetVolumeInformationW API function:

This function returns the volume serial number that the operating system assigns when a hard disk is formatted. To programmatically obtain the hard disk's serial number that the manufacturer assigns, use the Windows Management Instrumentation (WMI) Win32_PhysicalMedia property SerialNumber.

It appears that accessing information in WMI is more complex that simply invoking an API function.

Regards, John

Comment
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 10 February 2021 16:05 PM UTC
  2. PowerBuilder
  3. # 3

Hi Luis;

  You can grab the code right out of the STD Framework ... for example:

  Here is a list of the most recent framework release features ...

http://chrispollach.blogspot.com/2021/01/2020r2.html

  For the HD stuff, have a look in the "nc_app_controller_master" object class within the "STD_FC_Base.pbl" library and review the HD code in the "of_set_powerbuilder_environment_info" method.

  Feel free to grab any relevant code you need.

HTH

Regards ... Chris

Comment
  1. John Fauss
  2. Thursday, 11 February 2021 14:39 PM UTC
My research indicates that the GetVolumeInformation API function returns the OS-managed "serial number", which can change if the disk is formatted. If this is adequate for your needs, then great! If you require the manufacturer-assigned serial number of the hard drive, you must use WMI (Windows Management Instrumentation) in order to obtain this value. It looks like the easiest way to accomplish that in PB is to use C#/..NET code...I've been able to get close using OLEObject in PowerScript, but (I've not been able to access the individual properties of the Win32_DiskDrive class yet.
  1. Helpful
  1. Chris Pollach @Appeon
  2. Thursday, 11 February 2021 20:01 PM UTC
Hi Guys ... John is correct.
  1. Helpful
  1. John Fauss
  2. Thursday, 11 February 2021 22:18 PM UTC
** Update **

I've figured out how to extract information from WMI such as the serial number from a hard drive using only PowerScript code and PB OLEObject objects; NO external function declarations and NO API function calls needed. I'll post the code in a separate reply in this thread later today.
  1. Helpful
There are no comments made yet.
Mark Goldsmith Accepted Answer Pending Moderation
  1. Friday, 12 February 2021 04:28 AM UTC
  2. PowerBuilder
  3. # 4

Hi everyone,

As John Fauss mentioned you could accomplish this utilizing C#/ .Net and even PowerShell. Below are a couple of additional ways to obtain the serial number:


1) Using the Run() function and passing it the WMIC command; this is the less desirable way as it sends the output to a file which then has to be parsed but it can be done by using regular FileOpen etc. commands and parse what you need (I assume one knows how to do this so code not included). It would look as follows:
   String ls_command
   ls_command = 'cmd /c wmic diskdrive where "name like ' + "'%PHYSICALDRIVE0%'" + '" get  name,SerialNumber > driveinfo.txt'
   Run(ls_command)


2) The second way is preferred and is implemented using an OLEObject connecting to MSScriptControl.ScriptControl with VBScript...all inside PowerScript. It looks as follows:

//Declare necessary variables
OLEObject ole_wmi
Any la_DiskDrives[]
string ls_information

//Connect to OLEObject and build the function
ole_wmi = CREATE OLEObject
ole_wmi.ConnectToNewObject("MSScriptControl.ScriptControl")
ole_wmi.Language = "VBScript"
ole_wmi.AddCode('Function rtnDiskDrives()~r~n' &
+ 'DIM objDiskDrives(2)~r~n' &
+ 'strComputer = "."~r~n' &
+ 'Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")~r~n' &
+ 'Set colItems = objWMIService.ExecQuery("SELECT name, SerialNumber FROM Win32_DiskDrive")~r~n' &
+ 'For Each objItem in colItems~r~n' &
+ 'If objItem.Name = "\\.\PHYSICALDRIVE0" Then ~r~n' &
+ 'objDiskDrives(0) = objItem.Name~r~n' &
+ 'objDiskDrives(1) = objItem.SerialNumber~r~n' &
+ 'End If~r~n' &
+ 'Next~r~n' &
+ 'rtnDiskDrives = objDiskDrives~r~n' &
+ 'End Function')

//Call the function
la_DiskDrives[] = ole_wmi.Eval("rtnDiskDrives")
ole_wmi.DisconnectObject()
DESTROY ole_wmi

//Present the information about the harddrive
ls_information = "Disk Drive: " + string(la_DiskDrives[1]) + "~r~n" + &
 "Serial Number: " + string(la_DiskDrives[2]) + "~r~n"
MessageBox("Harddrive Information", ls_information)


In the above examples I'm assuming the drive required is Physical Drive 0 but it could be any drive on the system and both of the above approaches could be modified to include all drives.


I look forward to seeing your approach John and how you went about it, which OLEObject you used etc.
HTH.
Regards,
Mark

Comment
  1. John Fauss
  2. Friday, 12 February 2021 05:23 AM UTC
Hi, Mark - I really appreciate to posting your code for everyone (including me) to examine, so many thanks for doing that! I was slightly overly optimistic when I stated earlier I would post my code later today...that won't happen as it is very close but not quite ready to go - but I WILL post it tomorrow. I'm creating a small, simple, single-window app to illustrate how you can get any/all properties from logical disks and physical drives, not just the serial number. Stay tuned.
  1. Helpful
  1. Sivaprakash BKR
  2. Friday, 12 February 2021 07:17 AM UTC
In the first approach wmic should be available in the path. In my test, earlier, it failed in a couple of computers as that folder was not included in the path.
  1. Helpful
  1. Mark Goldsmith
  2. Friday, 12 February 2021 15:22 PM UTC
Hi Sivaprakash,



Yes, you're absolutely right. The ability to use that approach is dependent on "C:\Windows\System32\wbem" being set in the path or the full path must be provided. As well, the ability to run this command on client machines may also depend upon GPO (group policy settings) and so may require elevated permissions.
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Friday, 12 February 2021 16:39 PM UTC
  2. PowerBuilder
  3. # 5

As promised, attached is a small, single-window sample application (developed using PB 2017 R3) that demonstrates how to obtain the properties (including the serial number) of logical disks and physical disk drives.

I've used the PB OLEObject object, which utilizes COM, to interface with the Windows Management Instrumentation (WMI) service. No external functions are used. This uses a different approach than what Mark has done, which is not to imply is is any better or worse... it's just another way to accomplish the objective. You should be able to adapt the technique I've used to obtain other kinds of information out of WMI, but I haven't had a chance to do so, yet.

There may or may not be security/policy implications for accessing WMI information... I don't know and haven't looked into that.

Of course, I'd love to get feedback. If this proves helpful to anyone, I can post this sample app in CodeXchange so that others can find it easily.

Enjoy. Stay safe!

Attachments (1)
Comment
  1. Mark Goldsmith
  2. Friday, 12 February 2021 21:05 PM UTC
That's really great stuff John, nice work!! I thought in another posting you said you had a day job lol? Very flexible and complete...I absolutely see this being adaptable for other WMI classes.



I migrated this to PB 2019R3 without any issues. Actually created an executable as well which also ran without issues. Nice!
  1. Helpful
  1. John Fauss
  2. Saturday, 13 February 2021 00:29 AM UTC
You're very kind. Thank you, Mark!

I think I will generalize the sample app a little more and allow you to pick from any of the defined WMI Win32_xxxxx hardware classes. I played around and tried a variety of the classes and the ones I tried all work using the same technique to obtain all of the property names/values, Some of the data values are considerably larger than the 128 bytes I allocated in the display DataWindow, but that will be a simple change. I appreciate the feedback!
  1. Helpful
  1. Sivaprakash BKR
  2. Saturday, 13 February 2021 12:32 PM UTC
Commendable job indeed John. Will include it in my library.
  1. Helpful
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Friday, 12 February 2021 18:08 PM UTC
  2. PowerBuilder
  3. # 6

Thanks Mark ... works great!   :-)

Comment
  1. Mark Goldsmith
  2. Friday, 12 February 2021 21:12 PM UTC
You're welcome Chris...I think lol...I couldn't tell by the time of your posting whether you may have used my approach or John's application (if you haven't seen John's yet take a look, very nice). If it was mine did you use the Run command or the VBScript OLEObject?

Regards,



Mark
  1. Helpful
  1. Chris Pollach @Appeon
  2. Friday, 12 February 2021 21:17 PM UTC
I used yours Mark (OLE approach).
  1. Helpful
  1. Mark Goldsmith
  2. Friday, 12 February 2021 22:01 PM UTC
Thanks for the feedback Chris. I noticed in your Log Viewer screenshot the line item with the Hard Drive Name you also included (Manufacturer). This too is available when the manufacturer provides it otherwise it will show "Standard disk drives". It can be added by including manufacturer in the select statement as well as the model identifier so the entire select statement would look as follows: "SELECT name, SerialNumber, manufacturer, model FROM Win32_DiskDrive". You'd just need to add two additional array elements to store those values too.

Thanks again Chris.

Regards,

Mark
  1. Helpful
There are no comments made yet.
Sivaprakash BKR Accepted Answer Pending Moderation
  1. Monday, 22 February 2021 06:06 AM UTC
  2. PowerBuilder
  3. # 7

John Fauss

After working with your diskproperties utility, I found small corrections need to be done when listing the serial number of (external) USB flash drives.  [It applies only to USB flash drives only and doesn't affect when fetching data for fixed hard disk].

The serial numbers are still needed to be extracted from 

PNPDeviceID                      SerialNumber
USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_16GB&REV_8.07\035703RN&0 0 
USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_32GB&REV_1100\64FSVTV19XPJ7HZ2&0 AA00000000000485 

For the two USB Flash Drives that I tested I got the serial numbers like 0 and AA00000000000485, but the actual serial numbers are 035703RN and 64FSVTV19XPJ7HZ2.  These two values are part of the PNPDeviceID that this utility lists.

Hope you can check at your end and let us know the results.

Happiness Always
BKR Sivaprakash

 

Comment
  1. John Fauss
  2. Monday, 22 February 2021 21:18 PM UTC
I'll check this out tonight, as I do not have a USB drive on hand right now. What you're seeing might be due to the way Windows interfaces with USB drives...they are not the same as a hard disk...they are a Plug-n-Play device that Windows considers a logical drive. I'll report back when I know more.
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Tuesday, 23 February 2021 02:09 AM UTC
  2. PowerBuilder
  3. # 8

** Update **

The WMI Class Properties Inspector sample application mentioned in this post is now available in the PowerBuilder section of CodeXchange.

I inserted a 32GB SanDisk USB flash drive into a USB port, which my PC running Windows 10 Pro promptly recognized and made available as logical drive E:. It is listed as a removable disk drive in the Win32_DiskDrive WMI class:

A serial number is shown for the flash drive (circled above) as well as the Plug-and-Play (PNP) Device ID (also circled above). I do not know why you are not seeing the serial number property in your case.

Since the serial number for the flash drive appears to be present in the PNPDeviceID property value, you should be able to parse this string to obtain the desired value. Please note that property values of type String are encapsulated in double-quote characters. Also, if the string itself contains a double-quote character, the string will instead contain a backslash-double-quote combination, and a backslash character will be represented by a double-backslash combination. The above images are from a new, general-purpose WMI class properties inspection application I've been working on and will post in CodeXchange soon. This app removes the encapsulating double-quotes and the "escape'd" double-quote and backslash characters, which is why the values in the screen shots appear "normal".

I'm not a WMI expert...far from it, actually. If you need WMI-related help, I suggest you post a question on a Windows developer forum.

HTH

Regards, John

Comment
  1. Sivaprakash BKR
  2. Tuesday, 23 February 2021 10:54 AM UTC
Unfortunately this is not the case in my checking in both Win 7 and Win 10. I got different serial number [ from PnP Device id ] for one pen drive and 0 as serial number for the other pen drive.
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.