Разрешения WiX — установка разрешения для ранее существующего каталога

#permissions #wix

#разрешения #wix

Вопрос:

Я использую тепловую оболочку msbuild для создания списка компонентов для моего установщика веб-сайта и пытаюсь выяснить, как определить разрешения для папки в глубине этого дерева.

В моем сгенерированном файле wxs я получил

 <Directory Id="dirC092054A3A348CC48B696FD466A89A2F" Name="ExportFiles">
<Component Id="cmp699347B0054EDD7DD7B0935D39A66FAE" Guid="{5037..}">
  <File Id="..." KeyPath="yes" Source="SourceDirReportsExportFilesdonotdelete.txt" />
</Component>
</Directory>
  

И я понимаю, что мог бы использовать здесь CreateFolder и элемент Permission, но этот файл восстанавливается при предварительной сборке, поэтому я каждый раз терял бы свои изменения. Есть ли способ установить разрешение для папки ExportFiles из моего основного файла Product.wxs?

Комментарии:

1. Решением является использование XCACLS в качестве пользовательского действия: support.microsoft.com/kb/318754 . Таким образом, вы можете установить разрешения для пути вместо использования идентификатора.

Ответ №1:

Хотя ответ Сунила действительно работает, я нашел другой способ, которым решил поделиться.

Я использую метод, описанный здесь, чтобы получить heat.exe чтобы получить поэтапный вывод моего веб-приложения, но с несколькими изменениями:

 <Target Name="BeforeBuild">
<MSBuild Projects="%(ProjectReference.FullPath)" Targets="Package" Properties="Configuration=$(Configuration);Platform=AnyCPU" Condition="'%(ProjectReference.WebProject)'=='True'" />
<Copy SourceFiles="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj$(Configuration)TransformWebConfigtransformedweb.config" OverwriteReadOnlyFiles="true" DestinationFolder="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj$(Configuration)PackagePackageTmp" />
<PropertyGroup>
  <LinkerBaseInputPaths>%(ProjectReference.RootDir)%(ProjectReference.Directory)obj$(Configuration)PackagePackageTmp</LinkerBaseInputPaths>
</PropertyGroup>
<HeatDirectory OutputFile="%(ProjectReference.Filename)-temp.xml" Directory="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj$(Configuration)PackagePackageTmp" DirectoryRefId="INSTALLLOCATION" ComponentGroupName="%(ProjectReference.Filename)_Project" SuppressCom="true" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" AutoGenerateGuids="false" GenerateGuidsNow="true" ToolPath="$(WixToolPath)" Condition="'%(ProjectReference.WebProject)'=='True'" />
<XslTransformation XmlInputPaths="%(ProjectReference.Filename)-temp.xml" XslInputPath="XslTransform.xslt" OutputPaths="%(ProjectReference.Filename).wxs" />
  

  • Во-первых, задача копирования захватывает правильно преобразованный web.config, который, похоже, не произошел сам по себе (я получал токены в готовом конфигурационном файле).

  • Задача heat выводит данные во временный XML-файл, который я преобразую через XSLT в файл WXS, который будет получен WiX

Вот XSLT:

 <xsl:template match="@*|node()">
<xsl:copy>
  <xsl:apply-templates select="@*|node()" />
</xsl:copy>
  

 <xsl:template match="w:Directory[@Name='ExportFiles']/w:Component">
<w:Component>
  <xsl:attribute name="Id">
    <xsl:value-of select="@Id"/>
  </xsl:attribute>
  <xsl:attribute name="Guid">
    <xsl:value-of select="@Guid"/>
  </xsl:attribute>
  <w:CreateFolder>
    <w:Permission User="Administrators" GenericAll="yes" />
    <w:Permission User="Network Service" GenericAll="yes" />
  </w:CreateFolder>
  <xsl:apply-templates select="*" />
</w:Component>
  

Он просто воссоздает файл заново, за исключением папки ExportFiles, в которую добавлены биты разрешений:
Перед:

 <Directory Id="dirC092054A3A348CC48B696FD466A89A2F" Name="ExportFiles">
   <Component Id="cmp699347B0054EDD7DD7B0935D39A66FAE" Guid="{87D70A4F-A757-41C2-8AC9-E2904479FD45}">
     <File Id="filEC20935A3F97F24E20E1C2041AC766CA" KeyPath="yes" Source="SourceDirReportsExportFilesdonotdelete.txt" />
    </Component>
   </Directory>
  

После:

 <Directory Id="dirC092054A3A348CC48B696FD466A89A2F" Name="ExportFiles">
  <w:Component Id="cmp699347B0054EDD7DD7B0935D39A66FAE" Guid="{87D70A4F-A757-41C2-8AC9-E2904479FD45}"
    xmlns:w="http://schemas.microsoft.com/wix/2006/wi">
    <w:CreateFolder>
      <w:Permission User="Administrators" GenericAll="yes" />
      <w:Permission User="Network Service" GenericAll="yes" />
    </w:CreateFolder>
    <File Id="filEC20935A3F97F24E20E1C2041AC766CA" KeyPath="yes" Source="SourceDirReportsExportFilesdonotdelete.txt" />
  </w:Component>
 </Directory>
  

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

Ответ №2:

Создайте пользовательское действие, а затем установите разрешение для папки. Используйте этот код

 string directory = session["PATH"]   "Temp";
if (Directory.Exists(directory))
{
    DirectoryInfo dInfo = new DirectoryInfo(directory);
    DirectorySecurity dSecurity = dInfo.GetAccessControl();
    dSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl,
            InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None,
            AccessControlType.Allow));
    dInfo.SetAccessControl(dSecurity);
}
  

Этот код сделает папку общедоступной для всех.