Question

Je veux exécuter une action personnalisée dans un environnement Windows Installer (avec le script WiX) qui établit des liens symboliques à la fin de l'installation. mklink nécessite des privilèges d'administrateur, comme le programme d'installation restreint. C'est ce que je l'ai écrit:

<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>

Cela fonctionne parfaitement si l'UAC est complètement désactivé. Cependant, lors de l'activation de contrôle de compte tous les niveaux, cette action personnalisée échoue avec

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

même si je laissais dans la fenêtre de consentement. J'ai essayé de changer Exécuter à différé, Impersonate à pas, ou les InstallPrivileges de paquet de changement à élevée, aucun d'entre eux fonctionne.

Toute suggestion que je peux contourner? Merci!

Modifier : Code révisé avec l'action différée personnalisée

<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>
Était-ce utile?

La solution

fonctionne-t-il lorsqu'il est lancé à partir d'une commande administrateur rapide? Je suppose qu'il fait.

D'après ce que j'ai trouvé le msi ne peut pas augmenter le niveau qui est ce que l'UAC vous avez besoin. Je devais créer un setup.exe qui enveloppa le msi comme une ressource intégrée et l'a exécuté. Le setup.exe comprend le niveau d'exécution de la demande d'administrateur app.manifest qui soulève de manière appropriée le niveau 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>

je comprends tout simplement pas WIX, des actions personnalisées et assez contrôle de compte, mais c'est ce que je fini par faire.

Autres conseils

Êtes-vous le programmer entre InstallInitialize et InstallFinalize lorsque vous marquez Différé? Votre Avant et après l'air un peu bizarre:

InstallFinalize

_cmdline avant InstallFinalize

_mkline_exec après _cmdline

Sons un peu nondéterministe. Vous trouverez peut-être _cmdline survenant après InstallFinalize et différé, il ne fonctionnera pas.

Essayez:

InstallFinalize

_exec avant InstallFinalize

_cmldline avant _exec

Si elle est en fait MKLINK qui exige l'élévation, vous pouvez essayer d'utiliser Sysinternals junction.exe à la place.

J'ai fini par elevate.exe de Wintellect regrouper, déployer quelque dossier temporaire et lui fournir un chemin de script de ligne qui a créé tous les liens symboliques. Qu'il a été invoqué par l'action personnalisée. fichier de ligne de commande à son tour, a une certaine bonté à l'intérieur pour détecter le dossier approprié des fichiers de programme. ou l'obtenir à partir de la ligne de commande, si nécessaire. Il semble que même si WiX correctement élève l'action personnalisée, msi (ou Windows Installer) lui-même ne lui accorde pas de droits suffisants pour exécuter correctement mklink commande.

Notez également que Impersonate = "yes" dans le CA. Je crois que ce qui laissera msi pour montrer la boîte de dialogue d'élévation quand il exécute l'action.

fichier ligne de commande:

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"

dans le fichier 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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top