Installing 32-bit software as SYSTEM in Windows 7 x64

Hi,

I recently ran into an issue updating the Sun Java runtime on our x64 machines.  We don’t have the budget for fancy deployment solutions, so we just use a startup script (actually an executable, but that’s just fine-tuning) that checks the version number and runs the installer(s) as necessary.

Installing the 32-bit JRE results in error code 1619, which NET HELPMSG translates as “This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.”  Running the installer in interactive mode produces the same message.  The installer works normally when run from the context of a logged-in user.

Several hours of troubleshooting later, I identified the source of the problem.  Startup scripts run as local system.  In Windows 7, processes that run as local system have a special profile found in c:\windows\system32\config\systemprofile.  Unfortunately, on 64-bit systems, there are two system32 folders; one for 64-bit processes,and another (whose real name is syswow64) for 32-bit processes.  As a result, there are two separate system profiles; one for 32-bit, one for 64-bit.

So what?  Well, the Sun Java installer unpacks into a subfolder of the LocalLow application data directory.  In this case, the folder in question is c:\windows\system32\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24.  Because this is a 32-bit process, though, it is really writing to syswow64 instead of system32.

The Windows Installer, however, is a 64-bit process.  So when it is asked to open the MSI file, it’s looking in the wrong place; hence error code 1619.  The file can’t be opened because it can’t be found.

The same underlying problem (duplication of the system profile) seems to be the cause of this problem with Known Folders warning 1002 appearing repeatedly in the event log.  Some 32-bit system process is registering folder paths inside the (32-bit) system profile and of course these folders can’t be found by 64-bit processes.

For the problem with installing 32-bit software, there are a number of possible workarounds.  You could manually extract the installer files, copy them to a suitable path on the local system, and run them directly.  Most installers won’t mind this, although some will balk or fail to function properly.  Alternatively (and this is the solution I chose) you could create the necessary directory ahead of time and add a junction point (mklink /J) from the 64-bit profile to the 32-bit profile (note that this command line assumes you are in a 32-bit context, and has been split for readability):

mklink /J c:\windows\sysnative\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24
 c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24

This is the equivalent command if you are in a 64-bit context:

mklink /J c:\windows\system32\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24
 c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24

Another possible approach would be to merge the two system profiles together and create a junction point from one to the other.  That would solve this issue for all installers, as well as the Known Folders issue and any other variants.  However, I can’t recommend doing this; it’s too broad a change, and there’s no way to predict what it might break.  If you’re very brave, go ahead, but test thoroughly – and don’t blame me!

Hope this helps.

Harry.

Advertisements

Tags: , , ,

27 Responses to “Installing 32-bit software as SYSTEM in Windows 7 x64”

  1. nsturr Says:

    I think I found the core of the issue. The JRE wrapper uses the local variable USERPROFILE to determine where to unzip the MSI (and related) files. For a normal user these are located under C:\Users. However for the system account this is under C:\windows\system32. As you mentioned the system32 is different for the 32bit version (which is where the JRE puts it) vs. the 64bit version (where the Windows Installer looks). One option is to temporarily change the USERPROFILE environment variable to a non-windows32 directory, install the JRE, then change the variable back.

    • harryjohnston Says:

      [I had misunderstood nsturr’s comment; see below.]

      The installer should be asking the operating system where the profile folder is rather than using the USERPROFILE environment variable, but I wouldn’t be at all surprised if it behaves as you describe. So, yes, the procedure you describe is a simpler workaround than mine – thanks. Be wary, though, as this behaviour might change without warning in a future release.

      Note that if you just change the environment variable locally within the wrapper application or command script that is calling the installer, there is no need to reset it afterwards. This would be a safer approach than setting a persistent environment variable, which could affect other processes unexpectedly while the installer is running.

  2. nsturr Says:

    You are correct, there is some risk. And it was not the environment variable but ultimately what is set in the registry for S-1-5-18 SID (System Local) for the ProfileImagePath. Changing that and launching JRE works from the system account.

    • harryjohnston Says:

      Ah. As far as I know, changing ProfileImagePath manually is not supported. Since other processes will be running in the same context while you are doing this, with unpredictable consequences, I would consider it unacceptably risky.

  3. nsturr Says:

    I realized a simpler means to install this. A 32-bit application can launch a 64-bit application. Access to the 64-bit system32 is available via %windir%\sysnative. Place the JRE command (including command line options) into a jre.bat file in a location accessible by both 64/32 bit applications and launch %windir%\sysnative\cmd.exe /k jre.bat. That will launch the installer in a 64-bit space that will unload the CAB/MSI in the correct directory and Windows Installer will be able to find it. Verify that this works.

    • harryjohnston Says:

      Launching a 32-bit application from the 64-bit command line doesn’t make it run in a 64-bit context, any more than launching it from Explorer (which is of course also 64-bit) does. I don’t think this will work.

  4. nsturr Says:

    Sorry /c not /k. And you could just call the installer directly if you wanted to avoid the temp bat file.

    %windir%\sysnative\cmd.exe /c jre-6u20-windows-i586.EXE

  5. Mr. T Says:

    I’m trying to follow your method, but I just get an error message of system can’t find the path specified. If I create the directory first it says Cannot create a file when that file already exists. Any ideas of what I’m doing wrong?

    • harryjohnston Says:

      My mistake, actually. The command line I gave you only works if you run it in a 32-bit context. I’ve updated the post, and it now includes both 32-bit and 64-bit versions of the command line. Try the new one.

  6. Mr. T Says:

    Ah! It worked!! Thank you so much!

  7. RM_Dave Says:

    Great article!!! A huge help.

  8. PRhodes Says:

    Hello, please excuse my inexperience, but I was wondering where the mklink command goes when setting up the program? Does it go before the Java executable command in the “Command Line:” box? If so, are the separate commands separated with anything special in the box? Thanks for any info regarding this.

    • harryjohnston Says:

      I’m not sure what you mean by “the command line box”, but the mklink command needs to be executed before the Java installer is launched. How you would do this depends on how you are running the commands, e.g., what product you are using.

      • PRhodes Says:

        I am using SCCM 2007. I think the light bulb came on and I know what to do now. Getting ready to test!

  9. rich2323 Says:

    Thank you for putting this info together. I am still getting stuck after trying to get this to work.

    Here is a quick run down of what I have tried so far in my (32 bit)script that is running as a service(i am using autoit):

    1. download 32bit java file from java and place in “C:\TROYIT\java32.exe

    2. create directory “C:\windows\sysnative\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_25”

    3. create directory “c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_25”

    4. run “mklink /J C:\windows\sysnative\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_25 c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_25”

    5. run C:\TROYIT\java32.exe /s /L C:\TroyIT\java.log

    no matter what i have tried i keep getting error 1619 in the java install log file. If I manually run the script as a user, works fine.

    Any suggestions?

  10. rich2323 Says:

    i delete the directory and reran the script without step 2. same issue. How can i check to see if the junction is working to i cant browse to C:\windows\sysnative\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_25

    I can see the files in c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_25

    Rich

    • harryjohnston Says:

      I haven’t tried this with Java 7 yet, although that’s on my to-do list for this week. It might be different. What security context is your script running in? To see the junction, you’ll need to either use an elevated command prompt, log in with the Administrator account, or disable UAC.

    • harryjohnston Says:

      I can now confirm that this works with Java 7 for me. I’m not sure what’s going wrong in your environment.

  11. rich2323 Says:

    Security Context = highestAvailable

    Ill try the elevated command prompt, thanks again for you help

  12. rich2323 Says:

    local system account

  13. rich2323 Says:

    So for now I got around the issue by extracting the msi and cab files, then running the the msi silently to install. Its not optimal since there is not an easy way to extract the files from the executable but it will have to do for now.

    Thanks,

    Rich

  14. Bernhard Says:

    I don´t know what i´m doing wrong: I´m running this command prior to the java installation:

    mkdir c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_51
    mklink /J c:\windows\system32\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_51 c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.7.0_51

    But its only installing the 64 bit version. Any ideas?

  15. Bindu Says:

    Hi

    I am trying to install MSD Desktop Workbench v4,0,12 on 64bit machine with system context(PSEcec) , I am getting error “1628 failed to complete installation” . i tried with above solution but still that did not solve my issue . can please someone suggest how to proceed.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: