tags:

views:

467

answers:

2

I'm trying to convert the MSI product code GUID into the product code ID used to identify the installed item in the MSI registry keys. Is there an API for this? If not, how can this be done?

+2  A: 

Warning! Microsoft strongly recommends that you don't mess with their MSI Registry keys, but if you really must, here is a routine to translate a standard product code GUID to the key format used in the registry:

private static string TranslateMsiProductCode(Guid productCode)
{
    //  93 CE EF F6   AA 3D  4E 99   84 E1 8F FB F7 2C 43 0D  <--- Source
    //  6F FE EC 39   D3 AA  99 E4   48 1E F8 BF 7F C2 34 D0  <--- Target
    //  -----------   -----  -----   -----------------------
    //  01 23 45 67   89 01  23 45   67 89 01 23 45 67 89 01
    //  0                1                 2              3

    // examples:
    // {93CEEFF6-AA3D-4E99-84E1-8FFBF72C430D} -> 6FFEEC39D3AA99E4481EF8BF7FC234D0
    // {0E837AF0-4C92-4077-83F0-D022073F17C0} -> 0FA738E029C47704380F0D2270F3710C
    // {4AE61EA4-9F6F-4616-9035-0CF343EA462D} -> 4AE16EA4F6F961640953C03F34AE64D2


    string input = productCode.ToString("N").ToUpper();
    StringBuilder newString = new StringBuilder(input);

    newString[0] = input[7];
    newString[1] = input[6];
    newString[2] = input[5];
    newString[3] = input[4];
    newString[4] = input[3];
    newString[5] = input[2];
    newString[6] = input[1];
    newString[7] = input[0];

    newString[8] = input[11];
    newString[9] = input[10];
    newString[10] = input[9];
    newString[11] = input[8];

    newString[12] = input[15];
    newString[13] = input[14];
    newString[14] = input[13];
    newString[15] = input[12];

    newString[16] = input[17];
    newString[17] = input[16];
    newString[18] = input[19];
    newString[19] = input[18];
    newString[20] = input[21];
    newString[21] = input[20];
    newString[22] = input[23];
    newString[23] = input[22];
    newString[24] = input[25];
    newString[25] = input[24];
    newString[26] = input[27];
    newString[27] = input[26];
    newString[28] = input[29];
    newString[29] = input[28];
    newString[30] = input[31];
    newString[31] = input[30];

    return newString.ToString();
}
Todd Kobus
Nice! Looks like there's some opportunities there to simplify the char swapping and string reversals but thanks!
Jeff Paquette
A: 

Here's what I made in Perl, I stumbled across this question when searching for a more elegant way of doing it (no luck so far).

use strict;
use warnings;

my $guid;
if (shift() =~ /\{([0-9A-F\-]+)\}/)
{
    $guid = $1;
}

die "Usage $0: <guid>\n" unless $guid;

my @sections = split /-/, $guid;
die "Malformed guid $guid\n" if @sections != 5;

my $str;
for (my $i = 0; $i < 3; ++$i)
{
    $str .= reverse($sections[$i]);
}

my @tmp = split //, join('', @sections[3,4]);
for(my $i = 0; $i < @tmp; $i += 2)
{
    $str .= join('', @tmp[$i+1, $i]);
}

print "$str\n";
Motti

related questions