Using the <processtest> rule, we cannot distinguish the installer process from a running instance of the installed software itself (on OS X).

For example, the software we're installing is called "My Cool Software.exe" on Windows, and "My Cool Software.app" on OS X. When launching these applications, the processes have the following names:

"My Cool Software.exe" (Displayed by Task Manager on Windows)
"My Cool Software"     (Displayed by Activity Monitor on OS X)

Also, our installer requires administrative permissions, thus, our installer project defines the following project level variables:

  <fullName>My Cool Software</fullName>
  <installerFilename>${project.fullName} Setup.${platform_exec_suffix}</installerFilename>
  <requireInstallationByRootUser>1</requireInstallationByRootUser>

On Windows, this generates "My Cool Software Setup.exe", on OS X this generates "My Cool Software Setup.app".

Now, when launching the installer application on Windows, a process called "My Cool Software Setup.exe" is launched (which doesn't cause any problems).

On OS X, though, several processes are launched:

"My Cool Software Setup" (normal user)
"My Cool Software"       (normal user)
"My Cool Software"       (root user)

So on OS X, we cannot use the <processTest> rule, because the installer spawns two processes that have the same name as the installed software (i.e. "My Cool Software").

How to distinguish the installer process from our software?

PS: One way to solve this issue would be to make all the processes launched by the installer application to be named "My Cool Software Setup".

PPS: Another way to solve this would be to implement this feature request.

asked 26 Jun '15, 04:12

Dirk%20Stegemann's gravatar image

Dirk Stegemann
681273244
accept rate: 31%

edited 26 Jun '15, 04:16


For what it's worth, I implemented a new <ruleDefinition> that is able to check on OS X, whether a certain program is running, identified by its path (or path segment).

Feel free to re-use it.

Currently, the implementation runs the ps command line tool, then runs a <compareText> rule to check for a hard-coded path. Please adjust appropriately.


<ruleDefinition>
  <!--
      function:       isSoftwareRunning()
      parameter:      none
      Description:    Evaluates whether the application is running.
  -->
  <name>isSoftwareRunning</name>

  <parameterList>
      <!-- This function takes no parameters -->
  </parameterList>

  <actionList>

    <actionGroup>
      <!-- Rule actions performed on Windows -->
      <actionList>
        <if>
          <conditionRuleList>
            <ruleGroup>
              <ruleEvaluationLogic>or</ruleEvaluationLogic>
              <ruleList>
                <processTest logic="is_running" 
                             name="My Cool Software.exe" />
                <windowsServiceTest condition="is_running" 
                                    service="My Cool Software.exe" />
              </ruleList>
            </ruleGroup>
          </conditionRuleList>

          <actionList>
            <setInstallerVariable name="program_is_running" 
                                  value="true" />
          </actionList>

          <elseActionList>
            <setInstallerVariable name="program_is_running" 
                                  value="false" />
          </elseActionList>
        </if>
      </actionList>

      <ruleList>
          <platformTest type="windows" />
      </ruleList>
    </actionGroup>

    <actionGroup>
      <!-- Rule actions performed on OS X -->
      <actionList>
        <setInstallerVariableFromScriptOutput>
          <name>script_output_variable</name>
          <exec>ps</exec>
          <execArgs>-ax</execArgs>

          <!-- Error handling -->
          <abortOnError>0</abortOnError>
          <showMessageOnError>0</showMessageOnError>
          <onErrorActionList>
            <logMessage text="ERROR: script command failed" />

            <!-- In case of error, pretend the program is NOT running -->
            <setInstallerVariable name="program_is_running" 
                                  value="false" />
          </onErrorActionList>
        </setInstallerVariableFromScriptOutput>

        <if>
          <conditionRuleList>
            <compareText>
              <text>${script_output_variable}</text>
              <logic>contains</logic>
              <value>/Applications/My Cool Software.app/Contents/MacOS/My Cool Software</value>
            </compareText>
          </conditionRuleList>

          <actionList>
            <setInstallerVariable name="program_is_running" 
                                  value="true" />
          </actionList>

          <elseActionList>
              <setInstallerVariable name="program_is_running" 
                                    value="false" />
          </elseActionList>
        </if>
      </actionList>

      <ruleList>
          <platformTest type="osx" />
      </ruleList>
    </actionGroup>

    <logMessage text="INFO: ${platform_name}" />
    <logMessage text="INFO: Program is running: ${program_is_running}" />

  </actionList>

  <ruleList>
      <isTrue value="${program_is_running}" />
  </ruleList>

</ruleDefinition>

To provide a dialog that prevents the installation until the software in question has been closed, we're using the following action:

<actionDefinition>
  <!--
    function:       showErrorAndExitIfSoftwareIsInUse()

    parameter:      none

    Description:    Check whether the software is currently being used, 
                    which would prevent us from overwriting it. 
                    If it is, display an appropriate error message and 
                    exit the installer with an appropriate error code. 
  -->
  <name>showErrorAndExitIfSoftwareIsInUse</name>

  <parameterList>
      <!-- This function takes no parameters -->
  </parameterList>

  <actionList>
    <logMessage text="ENTER showErrorAndExitIfSoftwareIsInUse()" />

    <validatedActionGroup showMessageOnError="0" type="abortRetry">
      <severity>warning</severity>
      <text>${msg(StartupCheck.SoftwareInUse.Dialog.Text)}</text>

      <actionList>
        <throwError>
          <ruleList>
            <isSoftwareRunning />
          </ruleList>

        </throwError>
      </actionList>

      <onErrorActionList>
        <logMessage text="WARNING: Software is in use." />

        <exitWithExitCode exitCode="1" />
      </onErrorActionList>
    </validatedActionGroup>

    <logMessage text="EXIT showErrorAndExitIfSoftwareIsInUse()" />
  </actionList>

</actionDefinition>
link

answered 06 Jul '15, 10:12

Dirk%20Stegemann's gravatar image

Dirk Stegemann
681273244
accept rate: 31%

edited 07 Jul '15, 03:29

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:

×155
×9
×5
×3
×1

Asked: 26 Jun '15, 04:12

Seen: 2,919 times

Last updated: 07 Jul '15, 03:29