WiX: передача пути установки к управляемому настраиваемому действию - PullRequest
10 голосов
/ 01 декабря 2009

новый день, новая проблема ;-) Еще надо бороться с управляемыми настраиваемыми действиями. Мне уже удалось вызвать пользовательское действие и передать ему некоторые тестовые данные. Теперь я хочу заменить тестовые данные реальными данными, которые мне нужны. И тут начинаются проблемы: я хочу вызвать пакетный файл, который был установлен в подкаталог моей установки. Поэтому мне нужно передать путь установки к пользовательскому действию. Afaik это может быть сделано с помощью механизма обычного данных. Но это не работает. Когда я регистрирую установку, я вижу, что за пределами привязки INSTALLLOCATION указывает на правильный путь, но как только я смотрю в привязке, свойство customactiondata пусто ...

Может кто-нибудь взглянуть на мой код и дать мне подсказку, что я делаю неправильно? Спасибо за преимущество!

Модуль слияния, который вызывает настраиваемое действие:

<Module Id="DflHelpInstaller" Language="1033" Version="1.0.0.0">
    <Package Id="f952de58-1dc6-46b3-872a-7a49e2d9ea0a" Manufacturer="DflHelpInstaller" InstallerVersion="200" />

<Binary Id='RegisterDflHelpDll' SourceFile="$(var.REGISTERHELP.TargetDir)RegisterDflHelp.CA.dll" />

    <CustomAction Id='RegisterDflHelp' BinaryKey='RegisterDflHelpDll'  DllEntry='RegisterDflHelp' Execute='deferred' />

    <CustomAction Id="RegisterDflHelp.SetProperty" Return="check" Property="RegisterDflHelp" Value='[INSTALLLOCATION]' Execute='immediate' />


    <InstallExecuteSequence>
      <Custom Action='RegisterDflHelp.SetProperty' After='CostFinalize' />
      <Custom Action='RegisterDflHelp' After='InstallFiles' />
    </InstallExecuteSequence>

    <Directory Id="TARGETDIR" Name="SourceDir">
        </Directory>
    <ComponentGroupRef Id="HelpGroup"/>

    </Module>
</Wix>

Схема установщика Project, использующего модуль MergeModule:

....

<Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder" SourceName="PFFiles">
<Directory Id="Company" Name='$(var.COMPANY)'>
  <Directory Id="INSTALLLOCATION" SourceName='$var.v[SDK_VERSION]'>
    <Component Id="MyBanner" Guid="C8C28B92-9326-4991-BFB1-BBDFDF3653AB">
      <File Id ="Banner.bmp" Source="Banner.bmp" KeyPath="yes" DiskId="1"/>
    </Component>
    <Merge Id ="DflHelpInstaller" SourceFile="DflHelpInstaller.msm" Language="1033" DiskId="1" />
      </Directory>
</Directory>

....

    <Feature Id="Complete" Title="Setup" Description="Installs the SDK on your local machine." Display="expand" Level="1" ConfigurableDirectory="INSTALLLOCATION">
      <ComponentRef Id="Banner" />
      <ComponentRef Id ="UNINSTALLER"/>
      <ComponentGroupRef Id="ReferenceGroup"/>
      <MergeRef Id="DflHelpInstaller"/>
</Feature>

CustomAction:

   public class CustomActions
   { 
        [CustomAction]
        public static ActionResult RegisterDflHelp(Session session)
        {
            session.Log("Begin CustomAction1");
            session.Log("Before Access to customactiondata");

            //should contain the installation path - unfortunatelly it is empty! why?
            string cad = session["CustomActionData"];
            Debugger.Break();


            RegisterHelp(cad);

            session.Log("End of custom action..");
            return ActionResult.Success;
        }

Ответы [ 5 ]

18 голосов
/ 23 марта 2010

Если вы обозначите свои данные как ...

<CustomAction Id="MyCustomActionData" Return="check" Property="MyCustomAction" Value='PROPERTY0=[PROPERTY0];PROPERTY1=[PROPERTY1];PROPERTY2=[PROPERTY2]' Execute='immediate' />

Вы можете получить доступ к данным, как:

string property0 = session.CustomActionData["Property0"];
string property1 = session.CustomActionData["Property1"];
string property2 = session.CustomActionData["Property2"];

В предыдущем примере вы бы использовали:

<CustomAction Id="RegisterDflHelp.SetProperty" Return="check" Property="RegisterDflHelp" Value='INSTALLLOCATION=[INSTALLLOCATION]' Execute='immediate' />

тогда

string cad = session.CustomActionData["INSTALLLOCATION"];
5 голосов
/ 06 мая 2010

Я выполнил это, используя в файле .WXS следующее:

<Directory Id="TARGETDIR" Name="SourceDir">
 <Directory Id="ProgramFilesFolder" Name="PFiles">
  <Directory Id="ManufacturerDir" Name="Company" ShortName="Company">
   <Directory Id="INSTALLDIR" Name="TheApp">
    <Directory Id="BatchFileLocation" Name="BatchFiles">
     <Component Id="BatchFilesComp" ... >
      <File Id="SomeFile_BAT" Source="BatchFiles\SomeFile.bat" Name="SomeFile.bat" ... />
     </Component>
    </Directory>
   </Directory>
  </Directory>
 </Directory>
</Directory>

А в пользовательском действии:

var batchDirectory = session.GetTargetPath("BatchFileLocation");
var batchFile = batchDirectory + "SomeFile.bat"

Теперь я еще не выяснил, как избежать дублирования имени файла, но это успешно возвращает туда, где был установлен пакетный файл.

2 голосов
/ 30 мая 2014

После нескольких часов борьбы у меня сработало следующее:

string UserDefinedInstallDir = session["INSTALLDIR"];

Надеюсь, это поможет кому-то еще!

2 голосов
/ 31 декабря 2009

Вы передаете значение правильно, но попробуйте этот способ для ссылки на него.

        string[] keys = new string[session.CustomActionData.Keys.Count];
        session.CustomActionData.Keys.CopyTo(keys, 0);
        string cad = keys[0];

Это должно установить cad на путь установки, как вы хотите.

0 голосов
/ 07 декабря 2009

Вы пытались запросить свойство INSTALLLOCATION непосредственно из управляемого ЦС?

string cad = session["INSTALLLOCATION"];

Одна из прелестей использования DTF заключается в том, что у вас есть доступ на чтение / запись ко всем свойствам MSI без необходимости использования командных строк и т. Д. Поэтому, даже если INSTALLLOCATION нельзя запрашивать как обычное свойство, вы можете определить собственное свойство MSI. установите для него значение INSTALLOCATION и вместо этого запросите его внутри своего CA.

...