在预建步骤中获取InstallShield Limited版本中的版本号

时间:2014-05-16 13:55:54

标签: installshield-le

我想提取"产品版本"您在InstallShield Limited Edition部署项目的常规设置中键入的数字(aa.bb.cccc形式)。

具体来说,我想在自定义预构建步骤中执行此操作。理想情况下,我将其编码为使用WinAPI用C ++编写的可执行文件。

等到post构建步骤并从注册表中提取它为时已晚 - 它需要在复制项目文件之前发生。

有办法做到这一点吗?我不知道InstallShield为此定义的宏。可能只是免费版本不支持它。

1 个答案:

答案 0 :(得分:1)

如果您确实需要预先制作此版本,那么您恐怕非常幸运,因为相关选项在限量版中被禁用了。

但是,安装完成后,您可以从Windows注册表中提取版本,并触摸安装程序已删除的任何文件。以下是您可以用来完成第一部分的一些代码:

static const std::string key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; // Arguably the best place from which to obtain msi version data
static const unsigned MAX_KEY_LENGTH = 255; // Maximum length of a registry key

static const std::string displayName = /*ToDo - your display name here*/
static const unsigned displayNameSize = /*ToDo - the size of the display name here + 1 for the null terminator*/

int g_version; // The version number as it appears in the registry

HKEY hKey = NULL;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS){
    for (DWORD Index = 0; g_version == 0U; ++Index){
        DWORD cName = 256;
        char SubKeyName[MAX_KEY_LENGTH + 1/*Maximum length of a registry key is 255, add 1 for termination*/];
        if (RegEnumKeyEx(hKey, Index, SubKeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS){
            break;
        }
        HKEY hSubKey = NULL;
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (key + "\\" + SubKeyName).c_str(), 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS){
            // Is the DisplayName equal to displayName?
            DWORD dwType = REG_SZ;
            TBYTE buf[displayNameSize];
            DWORD dwSize = displayNameSize;
            HRESULT res;
            if ((res = RegQueryValueEx(hSubKey, TEXT("DisplayName"), NULL, &dwType, (PBYTE)&buf, &dwSize)) == ERROR_SUCCESS){
                if (!::strncmp(displayName.c_str(), (PTCHAR)buf, displayNameSize)){
                    // get the version
                    dwType = REG_DWORD;
                    dwSize = displayNameSize;
                    if (RegQueryValueEx(hSubKey, TEXT("Version"), NULL, &dwType, (PBYTE)&buf, &dwSize) == ERROR_SUCCESS && dwType == REG_DWORD){
                        g_version = (buf[3] << 24) + (buf[2] << 16) + (buf[1] << 8) + buf[0];
                    }
                }
            }
            RegCloseKey(hSubKey);
        }
    }
    RegCloseKey(hKey);
}

您已经提到过,您可以在可执行文件中对此进行编码。这可以作为构建后步骤运行,限制版支持。然后,您需要做的就是将版本号嵌入到您的一个安装文件中;您的可执行文件将能够执行的操作。