通过PHP获取制造商提供的硬盘序列号

5

获取硬盘序列号:如何通过PHP从制造商获取?我希望将其存储在文件中。

操作系统:Windows 2000、XP、ME、Vista...

是的,我需要服务器硬盘的序列号

或者可以通过Adobe AIR完成吗?或者可以通过Windows上的C程序完成吗?

C:\Documents and Settings\Administrator>dir
 Volume in drive C has no label.
 Volume Serial Number is BC16-5D5F

这个编号:BC16-5d5f 是硬盘唯一的吗?它与制造商提供的序列号有什么不同?

wmic DISKDRIVE GET SerialNumber

在我的Vista机器上,只显示以下文本:

序列号

在我的XP机器上,该命令无法识别。


你没有得到答案的原因是因为你特定的硬盘要么没有向操作系统提供这些信息,要么已经损坏了。 - OIS
9个回答

8
以下代码返回磁盘序列号。适用于多个驱动器,您将获得多个结果。只需使用shell_exec运行即可。
wmic DISKDRIVE GET SerialNumber

wmic.exe位于Windows系统32文件夹中。而且wmic在WinXP上确实存在,我自己也用过。

我的Vista测试结果:

C:\Windows\System32>wmic DISKDRIVE GET SerialNumber
SerialNumber
20202020202054534241354c4*snip*

我不确定所有硬盘都会向操作系统提供序列号。

看起来,wmic命令仅在Windows XP Professional版、Windows Vista和Windows 7的专业版中可用。


我的研究得出结论,WMIC在Windows XP Professional上可用,但在Windows XP Home上不可用。你的Home版本有吗?我正在寻找一种获取一些信息的方法,我想使用WMIC。 - Dorothy
@coding_idiot 在我的Windows 7 Home Premium(64位)上可以运行。只需打开CLI窗口并键入上面的命令即可。 - OIS

5

PHP本身没有访问硬件的方式。

您需要:

  • 使用操作系统的命令,并使用system()exec()调用它
  • 编写一个PHP扩展,将返回所需信息

如果您正在使用Linux并具有必要的特权和配置,则可以使用$r = system("hdparm -I /dev/hda");(将hda替换为您的硬盘)来获取给定硬盘的序列号。


为了避免root访问,我们还可以使用ls /dev/disk/by-id/命令,参见我的回答 ;) - Fery W

2
hdparm -i /dev/sdX

这是关于Linux的内容,不确定Windows是否适用。您可以通过"system()"执行它。
请参考http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.hk.msdn.connection&tid=e41f0af2-2e76-4be6-9b7b-636e79ac0491&cat=zh_HK_3b03d742-993a-4f96-accd-1063c6bfd559&lang=zh&cr=HK&sloc=&p=1
这可能是一个解决办法。
另外,在命令提示符上运行"dir"后,它显示:
C:\Documents and Settings\Administrator>dir
 Volume in drive C has no label.
 Volume Serial Number is BC16-5D5F

这是您在寻找的内容吗?


那个卷(即分区)的序列号。 - vartec
这个编号 BC16-5d5f 对于硬盘来说是唯一的吗? 顺便问一下,这个编号是如何生成的?它与制造商提供的序列号有什么不同? - simplfuzz
2
那个数字对于硬件来说并没有什么用处。它只是在驱动器格式化时分配给卷的软件序列号。 - Nathan Garabedian

1

使用shell_exec运行以下内容(如有需要,请在命令提示符中进行测试):

wmic path win32_physicalmedia get Tag,SerialNumber

DISKDRIVE无法获取通过IDE通道插入的驱动器的实际序列号。以上内容似乎可以获取我所有驱动器的实际序列号。标签也将返回有关驱动器类型的信息,这可能有助于识别不同的驱动器。

示例输出:

SerialNumber     Tag
WD-WX55D33JQNZ4  \\.\PHYSICALDRIVE4
S1OKIJNH938475   \\.\PHYSICALDRIVE0
WD-CV44HJ5L765Y  \\.\PHYSICALDRIVE1
WD-WX41D65SD1UU  \\.\PHYSICALDRIVE2
WD-WXB1SD3OIJHG  \\.\PHYSICALDRIVE3
                 \\.\CDROM0

1

我不能告诉你答案,但我猜你需要朝扩展的方向寻找(甚至自己编写一个)。我怀疑这不是 PHP 核心的功能。

编辑:我忘记了 "exec" 的强大威力 :-/


0

你可以使用

    $hdserial =`wmic DISKDRIVE GET SerialNumber 2>&1` 

或者

    $hdserial =`wmic bios get serialnumber 2>&1` 

然后你可以回显它。

根据Patrick Daryll Glandien的提示,您可以在*nix基础机器上执行以下操作。 $hdserial= hdparm -I /dev/hda

hdparm -i /dev/sda 返回较少的信息。但是由于hdparm需要root访问权限,所以我无法在php中运行它。

'2>&1'部分来自这里的建议


这个答案在这里的wmic部分被接受了(https://dev59.com/WGvXa4cB1Zd3GeqPNuOr#iI3jnYgBc1ULPQZFcNRf)。 - Lenin
这与我的答案相同,只是晚了3年...而且之所以没有被接受,是因为问题发布者要么没有正确的wmic命令(因为他没有专业版),要么硬盘驱动器没有向操作系统提供序列号。 - OIS
@OIS 你的意思是我只是复制了你的答案吗? - Lenin
是的,你的BIOS示例是错误的,而你的Unix示例超出了范围。 - OIS
没有明显的理由可以支持你的说法。我认为这只是你的个人意见而已。 :) - Lenin

0
在基于*nix的机器上,您也可以使用ls /dev/disk/by-id/,因为hdparm需要root权限(请参见Patrick Daryll G.的答案)。
<?php
exec($command.' 2>&1', $output);
echo 'HDD: '.$output[0].'<br>';

$outputs = explode('_', $outputs[0]);
$outputs = end($outputs);
echo 'HDD-SN: '.$output.'<br>';

然后你会得到类似这样的东西

HDD: ata-HGST_XXX1234567890XX_ABCD123456789X  // <connection>-<hdd_model>_<hdd_sn>
HDD-SN: ABCD123456789X  // Your HDD Serial Number

0

试试这段代码,它能正常工作。

<?php
   function GetVolumeLabel($drive) {
       // Try to grab the volume name
       if (preg_match('#Volume Serial Number is (.*)\n#i', shell_exec('dir '.$drive.':'), $m)) {
          $volname = ' ('.$m[1].')';
       } else {
           $volname = '';
       }
   return $volname;
}

$serial = str_replace("(","",str_replace(")","",GetVolumeLabel("c")));
echo $serial;

?>

0
你需要从服务器还是客户端获取硬盘?由于PHP运行在服务器上,所以直接从客户端获取似乎不可能。
手册建议你可以在服务器上执行命令: http://nl2.php.net/manual/en/ref.exec.php 不幸的是,我对Unix了解不够,无法为您获取硬盘序列号。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接