使用Perl检查注册表版本

时间:2011-08-31 19:49:23

标签: windows perl scripting comparison registry

我需要去注册表并检查程序安装版本。我正在使用perl来处理很多其他事情,但注册表检查部分无法正常工作。程序版本必须为9.7及以上,因此它可以是9.8或9.7.5。

当我安装程序时,它显示9.7.4,但我只需要检查9.7。

Bellow是我去DisplayVersion,这是一个REG_SZ,显示9.7.4。

OR

我可以将VersionMajor和VersionMinor一起使用,这是一个REG_DWORD。其中Major为9,Minor为7.

$ProgVersion= `$rootpath\\system32\\reg\.exe query \\\\$ASSET\\HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{9ACB414D-9347-40B6-A453-5EFB2DB59DFA} \/v DisplayVersion`;  

if ($ProgVersion == /9.7/)

这不起作用我可以使它9.200它仍然有效。我尝试使用它,它仍然无法正常工作。下一部分假设如果从9.7开始需要安装新客户端。我试图使用大于或等于,但它没有用。

$ProgVersionMajor= `$rootpath\\system32\\reg\.exe query \\\\$ASSET\\HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{9ACB414D-9347-40B6-A453-5EFB2DB59DFA} \/v VersionMajor`;  

$ProgVersionMinor= `$rootpath\\system32\\reg\.exe query \\\\$ASSET\\HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{9ACB414D-9347-40B6-A453-5EFB2DB59DFA} \/v VersionMinor`;  

if (($ProgVersionMajor=~ /9/) && ($ProgVersionMinor=~ /7/))

正确执行此操作或修正我正在做的事情的任何帮助。

2 个答案:

答案 0 :(得分:1)

有几件事:

  • 您没有提到它,但您使用的是Perl模块Win32::TieRegistry吗?如果没有,你应该。它将使处理Windows注册表变得更加容易。

  • 在Perl文档中,您可以查看Version String下的Scalar Value Constructors。这将使操作版本字符串变得更加容易。版本字符串中包含多个小数位,或者以字母v开头。我总是用v作为前缀,以明确它的含义。

下面是一个示例程序,向您展示如何在比较中使用它们:

#! /usr/bin/env perl
#

use strict;
use warnings;

my $version = v4.10.3;

for my $testVersion (v3.5.2, v4.4.1, v5.0.1) {
    if ($version gt $testVersion) {
        printf qq(Version %vd is greater than test %vd\n), $version, $testVersion;
    }
    else {
        printf qq(Version %vd is less than test %vd\n), $version, $testVersion;
    }
}

请注意,我不能只打印版本字符串。我必须使用printfsprintf并使用%vd 矢量十进制格式将其打印出来。通过常规print语句打印版本字符串可能会导致各种各样的破坏,因为它们实际上是unicode表示形式。你把它们放在一个打印声明中,你不知道你得到了什么。

另请注意,您不要在它们周围加上引号!否则,你只需要将它们作为常规字符串。


NEW ANSWER

我试图找到一种方法将字符串转换为v-string而不下载像Perl::Version或(Version)这样的可选包,我突然读到v-strings已弃用,我不知道我想使用不推荐使用的功能。

所以,让我们试试别的......

我们可以简单地将版本号分成数组:

v1.2.3 => $version[0] = 1, $version[1] = 2, $version[2] = 3

使用以下代码:

my @version = split /\./, "9.7.5";
my @minVersion = split /\./, "9.7"

现在,我们可以将版本字符串的每个部分与另一部分相对应。在上面的示例中,我将@version的9与@version的9进行了比较等。如果@version9.6,我会比较6 } @version 7 @minVersion中的@minVersion并快速发现7是更高的版本号。但是,第二部分都是@minVersion。然后我看第三节。哎呦! @version仅包含两个部分。因此,/^\d+$/更大。

这是进行比较的子程序。请注意,我还通过0正则表达式验证每个部分是否为整数。我的子程序可以返回四个值:

  • 1:两者大小相同
  • 2:第一个数字更大
  • undef:第二个数字更大
  • my $minVersion = "10.3.1.3"; my $userVersion = "10.3.2"; # Create the version arrays my $result = compare($minVersion, $userVersion); if (not defined $results) { print "Non-version string detected!\n"; } elsif ($result == 0) { print "$minVersion and $userVersion are the same\n"; } elsif ($result == 1) { print "$minVersion is bigger than $userVersion\n"; } elsif ($result == 2) { print "$userVersion is bigger than $minVersion\n"; } else { print "Something is wrong\n"; } sub compare { my $version1 = shift; my $version2 = shift; my @versionList1 = split /\./, $version1; my @versionList2 = split /\./, $version2; my $result; while (1) { # Shift off the first value for comparison # Returns undef if there are no more values to parse my $versionCompare1 = shift @versionList1; my $versionCompare2 = shift @versionList2; # If both are empty, Versions Matched if (not defined $versionCompare1 and not defined $versionCompare2) { return 0; } # If $versionCompare1 is empty $version2 is bigger if (not defined $versionCompare1) { return 2; } # If $versionCompare2 is empty $version1 is bigger if (not defined $versionCompare2) { return 1; } # Make sure both are numeric or else there's an error if ($versionCompare1 !~ /\^d+$/ or $versionCompare2 !~ /\^\d+$/) { return; } if ($versionCompare1 > $versionCompare2) { return 1; } if ($versionCompare2 > $versionCompare1) { return 2; } } } :出了点问题。

以下是该计划:

{{1}}

答案 1 :(得分:0)

使用Win32 :: TieRegistry

你在答案中说过你没有使用Win32::TieRegistry。我只是想告诉你它对你的程序的可读性有什么作用:

你的方式

$ProgVersion= `$rootpath\\system32\\reg\.exe query \\\\$ASSET\\HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{9ACB414D-9347-40B6-A453-5EFB2DB59DFA} \/v DisplayVersion`;

使用Win32 :: TieRegistry

use Win32::TieRegistry ( TiedHash => '%RegHash', DWordsToHex => 0 );

my $key = $TiedHash->{LMachine}->{Software}->{Wow6432Node}->{Microsoft}->{Windows}->{CurrentVersion}->{Uninstall}->{9ACB414D-9347-40B6-A453-5EFB2DB59DFA}->{Version};
my $programValue = $key->GetValue;
my $stringValue = unpack("L", $programValue);

或者,您可以将其拆分:

my $MSSoftware = $TiedHash->{LMachine}->{Software}->{Wow6432Node}->{Microsoft};
my $uninstall = $MSSoftware->{Windows}->{CurrentVersion}->{Uninstall};
my $programVersion = $uninstall->{9ACB414D-9347-40B6-A453-5EFB2DB59DFA}->{Version};

看看阅读有多容易。您也可以使用它来测试密钥。

Word'o Warning :我面前没有Windows机器,因此我没有准确检查代码的有效性。请尝试玩弄它,看看你得到了什么。)