Hi,

Is there any way to use function like Add Directory to Path; remove Directory from Path with another environement variable? ex: in installation processus i add to MY_APP_PATH environement variable C:\TOTO result as: MY_APP_PATH=C:\BEFOREinstallExistingPAth;C:\TOTO

in my uninstaller, i want to remove my C:\TOTO but keep old (or newly installed Path) to go back to: MY_APP_PATH=C:\BEFOREinstallExistingPAth;OtherAfterExistingPath

thanks Arnaud

asked 16 Nov '11, 05:49

youm's gravatar image

youm
6113
accept rate: 0%


It is not possible to use the built-in actions directly. However, you can use the function below to achieve the same task.

You can put it inside <project> tag and then simply use it as follows:

<removeValueFromPathlist>
  <data>${env(MY_APP_PATH)}</data>
  <resultVariable>newpath</resultVariable>
  <value>C:\TOTO</value> 
</removeValueFromPathlist>
<addEnvironmentVariable>
  <name>MY_APP_PATH</name>
  <value>${newpath}</value>
</addEnvironmentVariable>

This will remove the path, properly handling per-platform differences (i.e. ; and : separators appropriately) and cases where the value is first, in the middle, last or only element in the variable.

The function definition is as follows:

<project>
<functionDefinitionList>
    <actionDefinition name="removeValueFromPathlist">
        <actionList>
            <setInstallerVariable name="separator" value=":"/>
            <setInstallerVariable name="separator" value=";">
                <ruleList>
                    <platformTest type="windows"/>
                </ruleList>
            </setInstallerVariable>
            <setInstallerVariableFromRegEx name="value" pattern="\" substitution="\\" text="${value}"/>
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}${separator}" substitution="${separator}" text="${data}">
                <ruleList>
                    <regExMatch pattern="${separator}${value}${separator}" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <setInstallerVariableFromRegEx name="data" pattern="^${value}${separator}" substitution="" text="${data}">
                <ruleList>
                    <regExMatch pattern="^${value}${separator}" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}$" substitution="" text="${data}">
                <ruleList>
                    <regExMatch pattern="${separator}${value}$" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <setInstallerVariableFromRegEx name="data" pattern="^${value}$" substitution="" text="${data}">
                <ruleList>
                    <regExMatch pattern="^${value}$" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <globalVariables names="${resultVariable}"/>
            <setInstallerVariable name="${resultVariable}" value="${data}"/>
        </actionList>
        <parameterList>
            <stringParameter name="data" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="value" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="resultVariable" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
        </parameterList>
    </actionDefinition>
</functionDefinitionList>
<!-- ... -->
</project>

EDIT: A more compact alternative would be (thanks to stasm!):

<functionDefinitionList>
    <actionDefinition name="removeValueFromPathlist">
        <actionList>
            <setInstallerVariable name="separator" value=":"/>
            <setInstallerVariable name="separator" value=";">
                <ruleList>
                    <platformTest type="windows"/>
                </ruleList>
            </setInstallerVariable>
            <setInstallerVariableFromRegEx name="value" pattern="([\\.{}()[\]*?+^$|-])" substitution="\\\1" text="${value}"/>
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}${separator}" substitution="${separator}" text="${data}" />
            <setInstallerVariableFromRegEx name="data" pattern="^${value}${separator}" substitution="" text="${data}" />
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}$" substitution="" text="${data}" />
            <setInstallerVariableFromRegEx name="data" pattern="^${value}$" substitution="" text="${data}" />
            <globalVariables names="${resultVariable}"/>
            <setInstallerVariable name="${resultVariable}" value="${data}"/>
        </actionList>
        <parameterList>
            <stringParameter name="data" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="value" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="resultVariable" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
        </parameterList>
    </actionDefinition>
</functionDefinitionList>
link

answered 16 Nov '11, 08:47

wojciechka's gravatar image

wojciechka ♦♦
7.8k61122
accept rate: 26%

edited 20 Jan '14, 12:16

juanjo's gravatar image

juanjo ♦♦
5.8k413

Since I found this code extremely useful, I thought I would share the one bug that I found in it and the fix. The problem is if the path to remove contains parentheses, such as Program File (x86) in Windows. The code above fails on the first regex pattern and exits the actionList, leaving the path behind.

To handle this special case, the following additional actions can be performed, which fixes the failure of "value" in the regex pattern:

<setInstallerVariableFromRegEx name="value" pattern="\(" substitution="\(" text="${value}"/>
<setInstallerVariableFromRegEx name="value" pattern="\)" substitution="\)" text="${value}"/>

So, the entire code could look something like this:

<project>
<functionDefinitionList>
    <actionDefinition name="removeValueFromPathlist">
        <actionList>
            <setInstallerVariable name="separator" value=":"/>
            <setInstallerVariable name="separator" value=";">
                <ruleList>
                    <platformTest type="windows"/>
                </ruleList>
            </setInstallerVariable>
            <setInstallerVariableFromRegEx name="value" pattern="\\" substitution="\\\\" text="${value}"/>
            <setInstallerVariableFromRegEx name="value" pattern="\(" substitution="\(" text="${value}"/>
            <setInstallerVariableFromRegEx name="value" pattern="\)" substitution="\)" text="${value}"/>
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}${separator}" substitution="${separator}" text="${data}">
                <ruleList>
                    <regExMatch pattern="${separator}${value}${separator}" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <setInstallerVariableFromRegEx name="data" pattern="^${value}${separator}" substitution="" text="${data}">
                <ruleList>
                    <regExMatch pattern="^${value}${separator}" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}$" substitution="" text="${data}">
                <ruleList>
                    <regExMatch pattern="${separator}${value}$" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <setInstallerVariableFromRegEx name="data" pattern="^${value}$" substitution="" text="${data}">
                <ruleList>
                    <regExMatch pattern="^${value}$" text="${data}">
                        <logic>matches</logic>
                    </regExMatch>
                </ruleList>
            </setInstallerVariableFromRegEx>
            <globalVariables names="${resultVariable}"/>
            <setInstallerVariable name="${resultVariable}" value="${data}"/>
        </actionList>
        <parameterList>
            <stringParameter name="data" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="value" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="resultVariable" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
        </parameterList>
    </actionDefinition>
</functionDefinitionList>
<!-- ... -->
</project>
link

answered 12 Jun '12, 22:49

DevHopeful_2012's gravatar image

DevHopeful_2012
176131521
accept rate: 9%

The dot symbol often occurs in path strings and should be escaped as well:

<setInstallerVariableFromRegEx name="value" pattern="\." substitution="\." text="${value}"/>

(20 Jan '14, 04:03) stasm

I don't quite understand why latter <setInstallerVariableFromRegEx...> have <ruleList> restrictions. Isn't setInstallerVariableFromRegEx apply only if the "text" matches the "pattern"?

Shouldn't it be just:

<setInstallerVariableFromRegEx name="data" pattern="${separator}${value}${separator}" substitution="${separator}" text="${data}" /> ?

(20 Jan '14, 04:11) stasm

Actually, the function I use deletes the environment variable, if it is an exact match, assuming we created it (or that it is now obsolete). I probably didn't do the best job of sharing/porting my code to fit the "remove only" use case.

(25 Aug '15, 10:03) DevHopeful_2012

It seems the code of removeValueFromPathlist can be improved and simplified.

First, escaping all regex special symbols in one action:

<setInstallerVariableFromRegEx name="value" pattern="([\\.{}()[\]*?+^$|-])" substitution="\\\1" text="${value}"/>

Second, <ruleList> restrictions for <setInstallerVariableFromRegEx> are unnecessary in this case and can be removed.

So entire function is defined as follows:

<functionDefinitionList>
    <actionDefinition name="removeValueFromPathlist">
        <actionList>
            <setInstallerVariable name="separator" value=":"/>
            <setInstallerVariable name="separator" value=";">
                <ruleList>
                    <platformTest type="windows"/>
                </ruleList>
            </setInstallerVariable>
            <setInstallerVariableFromRegEx name="value" pattern="([\\.{}()[\]*?+^$|-])" substitution="\\\1" text="${value}"/>
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}${separator}" substitution="${separator}" text="${data}" />
            <setInstallerVariableFromRegEx name="data" pattern="^${value}${separator}" substitution="" text="${data}" />
            <setInstallerVariableFromRegEx name="data" pattern="${separator}${value}$" substitution="" text="${data}" />
            <setInstallerVariableFromRegEx name="data" pattern="^${value}$" substitution="" text="${data}" />
            <globalVariables names="${resultVariable}"/>
            <setInstallerVariable name="${resultVariable}" value="${data}"/>
        </actionList>
        <parameterList>
            <stringParameter name="data" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="value" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
            <stringParameter name="resultVariable" description="" explanation="" value="" default="" allowEmptyValue="0" width="0"/>
        </parameterList>
    </actionDefinition>
</functionDefinitionList>
link

answered 20 Jan '14, 11:58

stasm's gravatar image

stasm
15457
accept rate: 0%

Thanks! I have added your alternative to the response.

(20 Jan '14, 12:16) juanjo ♦♦
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×41
×14
×13
×1

Asked: 16 Nov '11, 05:49

Seen: 2,278 times

Last updated: 25 Aug '15, 10:03