слишком длинная строка с MsiGetProperty с Installshield Installscript

Я использую MsiGetProperty для получения значения строкового параметра от установщика. И после этого я вызываю управляемую dll и передаю это значение:

  nvBufferSize = MAX_STRING;
  MsiGetProperty (hMSI, "DBHMS", sDbHost, nvBufferSize);  

когда я передаю значение sDbHost, оно выглядит так, когда я получаю его из управляемого кода: srvdata-02NULNULNULNULNULNUL...... однако в интерфейсе я написал просто «srvdata-02».

С тем же кодом все было в порядке с Installshield 2010, теперь я обновляю его до installshield 2012. У вас есть какое-нибудь решение?


person Cheb Bilel    schedule 22.05.2013    source источник


Ответы (2)


Некоторое время назад были внесены некоторые изменения в поведение MsiGetProperty. Попробуйте установить для nvBufferSize значение MAX_SIZE вместо MAX_STRING. Также проверьте код возврата MsiGetProperty, чтобы убедиться, что он равен ERROR_MORE_DATA или возвращает какой-то другой код. Наконец, проверьте значение nvBufferSize, чтобы узнать, сколько байтов необходимо.

Кстати, если вы просто пытаетесь маршалировать свойство в управляемый код, вы можете рассмотреть возможность изучения структуры инструментов развертывания (DTF) в XML установщика Windows (WiX). Это очень хороший SDK, который позволяет вам писать настраиваемые действия управляемого кода и упаковывать их, как если бы они были родными библиотеками Win32. Затем InstallShield может легко использовать это как пользовательское действие MSI DLL.

DTF предоставляет библиотеку взаимодействия и объект сеанса, который можно использовать следующим образом:

person Christopher Painter    schedule 22.05.2013
comment
MAX_SIZE не определен в InstallShield 2013. - person BuvinJ; 26.08.2015
comment
Думаю нет. Забавно, за 20 лет я забыл об InstallScript больше, чем помню. - person Christopher Painter; 26.08.2015

Как бы нелепо это ни казалось, вот вам работающее решение InstallScript:

nvBufferSize = MAX_STRING;
nResult = MsiGetProperty( ISMSI_HANDLE, szPropertyName, svValue, nvBufferSize );     
if( nResult = ERROR_MORE_DATA ) then 
    MsiGetProperty( ISMSI_HANDLE, szPropertyName, svValue, nvBufferSize );   
endif;

Первая попытка возвращает фактический необходимый размер буфера. Если это больше, чем максимальная строка (1024?), Второй вызов получает все это.

В качестве альтернативы я обнаружил, что могу сразу же присвоить nvBufferSize большее значение, например. 4096 и использовать его с одним вызовом (при условии, что данные больше не были этим пределом). Однако двойной вызов более надежен.

Согласно: https://msdn.microsoft.com/en-us/library/aa370134(v=vs.85).aspx функция API предназначена для возврата размера буфера путем передачи пустого литерала ("") вместо строковой переменной. InstallScript 2013 выдает ошибку компиляции, если вы попытаетесь это сделать...

person BuvinJ    schedule 25.08.2015
comment
Сделайте еще один шаг и оберните его во вспомогательную функцию. Да, вот как это работает... хотя я не могу сказать, что действительно часто использую InstallScript в эти дни. Обычно я просто выбираю настраиваемое действие DTF/C#, поскольку .NET 2.0 или новее уже должны быть практически на каждой машине. - person Christopher Painter; 26.08.2015
comment
Я согласен. В идеале вы бы вставили это в функцию в сценарии включения утилиты. Я понимаю ваш уход от InstallScript. Я использую его в InstallShield в основном для непрерывности всего этого. - person BuvinJ; 26.08.2015
comment
Пик InstallScript для меня пришелся на 10 лет назад. blog.iswix.com/2005/03/custom-actions.html blog.iswix.com/2006/04/installshield-12-beta2 .html - person Christopher Painter; 26.08.2015
comment
ИМО, это достойный язык. Это началось в то время, когда делать аналогичные вещи на C++ было намного сложнее. На протяжении многих лет они использовали взаимодействие COM и .NET. Однако пользовательские действия WiX DTF/C# очень хорошо интегрируются в InstallShield. Полностью исправленная коробка Windows XP будет иметь .NET 2.0. Виста вышла с 3.0 и так далее. Я пишу свои ЦС для CLR 2.0 и включаю файл конфигурации CustomAction, в котором говорится о привязке к 2.0 или 4.0. Теперь я могу использовать всю мощь библиотек базовых классов, и нет ничего такого, чего не мог бы сделать InstallScript. При этом автоматизация сборки требует немного больше работы. - person Christopher Painter; 26.08.2015