WiX: сделать символическую ссылку с включенным UAC - PullRequest
2 голосов
/ 31 августа 2010

Я хочу выполнить пользовательское действие в установщике Windows (со скриптом WiX), который создает символические ссылки в конце установки. mklink требует прав администратора, поскольку установщик ограничивает. Вот что я написал:

<CustomAction Id="mklink_cmdline" Property="QtExecCmdLine" Value='"[SystemFolder]cmd.exe" /c mklink "[SystemFolder]my_app.dll" "[INSTALLDIR]my_app.dll"' />
<CustomAction Id="mklink_exec" BinaryKey="WixCA" DllEntry="CAQuietExec" Return="ignore" />

...

<InstallExecuteSequence>
    <Custom Action="mklink_cmdline" Before="InstallFinalize">
        ...
    </Custom>
    <Custom Action="mklink_exec" After="mklink_cmdline">
        ...
    </Custom>
    ...
</InstallExecuteSequence>

Это прекрасно работает, если UAC полностью отключен. Однако при включении контроля учетных записей на любом уровне это настраиваемое действие завершается с

CAQuietExec:  You do not have sufficient privilege to perform this operation.

, даже если я позволил в окне согласия. Я попытался изменить Выполнение на отложенное, Олицетворение на Нет или изменить InstallPrivileges пакета на повышенные, ни один из них не работает.

Любое предложение, которое я могу обойти? Спасибо!

Редактировать : исправлен код с отложенным настраиваемым действием

<CustomAction Id="mklink_cmdline" Property="mklink_exec" Value='"[SystemFolder]cmd.exe" /c mklink "[SystemFolder]my_app.dll" "[INSTALLDIR]my_app.dll"' />
<CustomAction Id="mklink_exec" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Impersonate="no" Return="ignore" />

...

<InstallExecuteSequence>
    <Custom Action="mklink_exec" Before="InstallFinalize">
        ...
    </Custom>
    <Custom Action="mklink_cmdline" Before="mklink_exec">
        ...
    </Custom>
    ...
</InstallExecuteSequence>

Ответы [ 4 ]

1 голос
/ 08 сентября 2010

Работает ли он при запуске из командной строки администратора?Я предполагаю, что это так.

Из того, что я обнаружил, msi не может поднять уровень UAC, что вам и нужно.Мне пришлось создать файл setup.exe, который обернул msi как встроенный ресурс и выполнил его.В setup.exe входит app.manifest, запрашивающий уровень выполнения администратора, который соответствующим образом повышает уровень UAC:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <assemblyIdentity version="1.0.0.0" name="Setup.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
</asmv1:assembly>

Возможно, я просто недостаточно разбираюсь в WIX, пользовательских действиях и UAC, но это то, что я в итоге сделал.

0 голосов
/ 22 февраля 2012

Я закончил сборку elevate.exe из wintellect, развернул ее в какой-то временной папке и предоставил путь к сценарию командной строки, который создал все символические ссылки.Чем он был вызван через пользовательское действие.Файл командной строки, в свою очередь, обладает некоторыми достоинствами для определения правильной папки программных файлов.или получить его из командной строки, если это необходимо.Похоже, что хотя WiX правильно повышает значение настраиваемого действия, msi (или установщик Windows) не предоставляет ему достаточных прав для правильного запуска команды mklink.

Также обратите внимание, что Impersonate = "yes" в ЦС.Я полагаю, что именно это позволит msi показывать диалоговое окно повышения прав при выполнении действия.

файл командной строки:

cd /D %~p0

IF EXIST "%PROGRAMFILES(x86)%" SET PROGFILES=%PROGRAMFILES(x86)%
IF "%PROGFILES%".=="". SET PROGFILES=%PROGRAMFILES%

SET INSTALLPATH=%PROGFILES%\MyGreatProduct
SET DATAPATH=%PROGRAMDATA%\MyGreatProduct

IF NOT "%~1."=="." SET INSTALLPATH=%~1
IF NOT "%~2."=="." SET DATAPATH=%~2

IF EXIST "%INSTALLPATH%" mklink "%INSTALLPATH%\veryimportant.ini" "%DATAPATH%\veryimportant.ini"

в файле wxs:

<Component Directory="TempFolder" Id='Comp_Temp_Makesymlinks' Guid='47a58219-1291-4321-4321-176987154921'>
    <File Id='makesymlinks_cmd' Source='makesymlinks.cmd'>
                <Permission User='Everyone' GenericAll='yes' />
    </File>
    <File Id='elevate_exe' Source='elevate.exe'>
                <Permission User='Everyone' GenericAll='yes' />
    </File>
</Component>

<SetProperty Id="CA_MakeSymLinksCmd" Before="CA_MakeSymLinksCmd" Sequence="execute" 
    Value="&quot;[TempFolder]\elevate.exe&quot; &quot;[TempFolder]\makesymlinks.cmd&quot;" />
<CustomAction Id="CA_MakeSymLinksCmd" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="ignore" Impersonate="yes" />

<InstallExecuteSequence>
    <Custom Action="CA_MakeSymLinksCmd" Before="InstallFinalize"><![CDATA[NOT Installed AND VersionNT >= 600 ]]></Custom>
</InstallExecuteSequence>
0 голосов
/ 20 сентября 2011

Если на самом деле mklink требует повышения прав, вместо этого вы можете попробовать использовать SysInternals junction.exe.

0 голосов
/ 31 августа 2010

Планируете ли вы это между InstallInitialize и InstallFinalize, когда вы помечаете его как Отложенный?Ваш До и после выглядит немного странным:

InstallFinalize

_cmdline перед InstallFinalize

_mkline_exec после _cmdline

Звучит немного недетерминировано.Вы можете обнаружить _cmdline, возникающий после InstallFinalize, и отложенный там не будет работать.

Попробуйте:

InstallFinalize

_exec перед InstallFinalize

_cmldline перед _exec

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...