Проверьте версию реестра с помощью Perl - PullRequest
0 голосов
/ 31 августа 2011

Мне нужно зайти в реестр и проверить версию установленной программы. Я использую Perl для множества других вещей, но часть проверки реестра не работает. Версия программы должна быть 9.7 и выше, чтобы она могла быть 9.8 или 9.7.5.

Когда я устанавливаю программу, она показывает 9.7.4, но мне просто нужно проверить 9.7.

Ниже я иду к DisplayVersion, который является REG_SZ, который показывает 9.7.4.

OR

Я мог бы использовать VersionMajor и VersionMinor вместе, который является REG_DWORD. Который для майора 9 и младший 7 *. 1009 *

$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 ]

1 голос
/ 01 сентября 2011

Несколько вещей:

  • Вы не упоминаете об этом, но используете ли вы модуль Perl Win32 :: TieRegistry ?Если нет, вы должны.Это значительно облегчит обработку реестра Windows.

  • В документации по Perl вы можете посмотреть Version String в Конструкторы скалярных значений ,Это значительно облегчит манипулирование строками версий.Строки версий имеют более одного десятичного знака или начинаются с буквы 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;
    }
}

Обратите внимание, что я не могу просто напечатать строки версий.Я должен использовать printf и sprintf и использовать %vd векторный десятичный формат , чтобы распечатать их.Печать строк версий с помощью регулярного оператора print может привести к разного рода разрушениям, поскольку они действительно представляют собой Unicode-представления.Вы помещаете их в заявление для печати и не знаете, что получаете.

Также обратите внимание, что вы не заключаете в них кавычки!В противном случае вы просто сделаете их обычными строками.


НОВЫЙ ОТВЕТ

Я пытался найти способ преобразовать строку в v-строку без загрузки дополнительного пакета, например Perl :: Version или (Version), и я вдруг прочитал, что v-строки устарели, и я не хочу использовать устаревшую функцию.

Итак, давайте попробуем что-то еще...

Мы могли бы просто разделить номера версий на составляющие их компоненты в виде массивов:

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

Используя следующий бит кода:

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

Теперьмы можем каждую часть строки версии против другой.В приведенном выше примере я сравниваю 9 @version с 9 @version и т. Д. Если бы @version было 9.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;
    }
}
}
0 голосов
/ 02 сентября 2011

Использование 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 передо мной, поэтому я нене проверяйте правильность кода. Попробуйте поиграть с ним и посмотреть, что вы получите.)

...