Wednesday, June 13, 2012

Re-Packaging Apple iTunes 10.6.1.7 and later

iTunes comes as an EXE file which can be extracted easily with 7Zip. The five MSI I received were AppleApplicationSupport, AppleMobileDeviceSupport64, AppleSoftwareUpdate, Bonjour64 and iTunes64. The Apple Software Update MSI and Bonjour MSI can be discarded if you do not want to AutoUpdate your iTunes. Bonjour can be kept if you want to allow file sharing on your desktop fleet. We did not want this so we removed this MSI. If you want to install Bonjour then it can be installed silently with /qb! switch.

From this Version QuickTime is not part of iTunes. QuickTime can be packaged separately. more details for packaging this is in this post:
http://msiworld.blogspot.com.au/2012/06/re-packaging-apple-quicktime-7728056.html

Apple Application Support and Apple Mobile Device Support MSI can be installed silently with /qb! switch.

You will have to customize iTunes by creating an MST file.

1) Change the following Public Properties in the MST:
DESKTOP_SHORTCUTS = 0
DISABLEADVTSHORTCUTS = 0
SCHEDULE_ASUW = 0
AMDS_IS_INSTALLED = 1
BONJOUR_IS_INSTALLED = 1
REBOOT = ReallySuppress
NO_ASUW = 0
NO_BONJOUR = 0
IAcceptLicense = Yes
REGSRCH_DESKTOP_SHORTCUTS = 0

2) Install iTunes on a test machine and make all the customizations you want. All the customizations will be stored in following files:

a) "%userprofile%\AppData\Local\Apple Computer\iTunes\cache.db
b) "%userprofile%\AppData\Local\Apple Computer\iTunes\iTunesPrefs.xml"
c) "%userprofile%\AppData\Roaming\Apple Computer\iTunes\iTunesPrefs.xml"
d) "%userprofile%\AppData\Roaming\Apple Computer\iTunes\Preferences\com.apple.iTunes.plist"
e) "%userprofile%\AppData\Roaming\Apple Computer\iTunes\Preferences\keychain.plist"

Copy these files in C:\ProgramData\Apple Computer\iTunes\ folder in your MST file and then use the below script to run in Custom Action just before InstallFinalize. Condition to be kept as NOT REMOVE~="ALL"


'Created by Piyush Nasa
'Used to copy the config file to the current user\appdata\local directory.
on error resume next
Set oShell = CreateObject( "WScript.Shell" )
userprofile=oShell.ExpandEnvironmentStrings("%USERPROFILE%")
systemdrive=oShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%")
Set fso = CreateObject("Scripting.FileSystemObject")
Set afile = fso.GetFile(systemdrive & "\ProgramData\Apple iTunes\local\cache.db")
strDestination1 =userprofile & "\AppData\Local\Apple Computer\iTunes\cache.db"
Set bfile = fso.GetFile(systemdrive & "\ProgramData\Apple iTunes\local\iTunesPrefs.xml")
strDestination2 =userprofile & "\AppData\Local\Apple Computer\iTunes\iTunesPrefs.xml"
Set cfile = fso.GetFile(systemdrive & "\ProgramData\Apple iTunes\Roaming\iTunesPrefs.xml")
strDestination3 =userprofile & "\AppData\Roaming\Apple Computer\iTunes\iTunesPrefs.xml"
Set dfile = fso.GetFile(systemdrive & "\ProgramData\Apple iTunes\Roaming\Preferences\com.apple.iTunes.plist")
strDestination4 =userprofile & "\AppData\Roaming\Apple Computer\iTunes\Preferences\com.apple.iTunes.plist"
Set efile = fso.GetFile(systemdrive & "\ProgramData\Apple iTunes\Roaming\Preferences\keychain.plist")
strDestination5 =userprofile & "\AppData\Roaming\Apple Computer\iTunes\Preferences\keychain.plist"

fso.CreateFolder(userprofile & "\AppData\Local\Apple Computer")
fso.CreateFolder(userprofile & "\AppData\Local\Apple Computer\iTunes")
fso.CreateFolder(userprofile & "\AppData\Roaming\Apple Computer")
fso.CreateFolder(userprofile & "\AppData\Roaming\Apple Computer\iTunes")
fso.CreateFolder(userprofile & "\AppData\Roaming\Apple Computer\iTunes\Preferences")
afile.Copy(strDestination1)
bfile.Copy(strDestination2)
cfile.Copy(strDestination3)
dfile.Copy(strDestination4)
efile.Copy(strDestination5)

3) Add any HKCU registry key in a new component placed at the highest parent Feature. Set this as a keypath. This will ensure that the application is self healed when launched by the user.

Please note that this package works fine when deployed/installed through any deployment tool in System context as it will trigger the self heal. If you have to manually install this application then you need to add the file the LOCALAPPDATAFOLDER manually in your transform.

Hope this will expidite your packaging of iTunes application.

25 comments:

Dan said...

Freaking apple.... 2 config files with the same name (itunes.xml), in different locations storing different settings... Confusing.

FYI: You can merge the two xml files into 1 universal file. I think I just used notepad and copied data from one to the other to create 1 master, then copied same file to both locations.

I installed the itunes.xml to installdir, then used duplicate files table to copy them to their respected locations during self-heal.

A bit more complex then vbs (you have to build directory structure etc), but all native msi logic, which never hurts during upgrades.

Piyush Nasa said...

Hi Dan, Somehow I have not had a good experience with Duplicate File table so I try to avoid it. It is totally a packagers choice how he wants to deploy a thing. I have just showcased a way to do it.

Anonymous said...

I'm having a really hard time with this version of iTunes. I've done all the advised changes in an MST. I don't have to touch the profiles, because default settings are in order. It seems that the vendorMSI does absolutely nothing with the MST. I keep getting the EULA and the autoupdate message. Can anyone verify the proposed changes in the MST?

Piyush Nasa said...

Can you tell what is the commandline you are using with Transform. Hope that is correct.

How to install iTunes said...

In a multiple package transaction, can we create a single transaction from multiple packages.

Piyush Nasa said...

You cannot create a single transaction but there are ways in which you can check if any of it has failed and try to install it again.
In SCCM you can create different packages for each application and then chain their installs.
If you want to use VBScript to install them one after the other then I will suggest you to check exit codes for msi install and based on that you can take further actions. I would suggest you to this link where you can get more information on this:
http://fuznik.blogspot.com.au/2012/09/scripts-and-exit-codes.html

Unknown said...

Hi, I have followed your instructions and it almost works on version 11.0.2. Im wondering what I am doing wrong. I run the installer with the changes and script. I installed this as the system account using Task Scheduler. After installation I run the program with an admin account and everything works. When I do the same thing with a user who has basic rights, It copies the prefs and then right before launch somehow repairs this and its reset back to the original itunes prefs and the Eula comes up. I have the script running in a ca right before InstallFinalize and running in Commit Execution. I also have done deferred and same effect. any thoughts?

Piyush Nasa said...

Hi David,
Where is your original iTunes.prefs file?
Try not keeping your original prefs file and let the package copy the new one. You need to modify your prefs file and use that only not the original one.

Unknown said...

I 'customized' my preferences. Have the MSI copy them to C:\ProgramData\Apple Computer\iTunes\local and Roaming. So the script is pulling from the customized preferences. In fact I see them get copied and then almost immediately change. I believe the customized pref is 1300kb and then it changes to 15kb. I can send you some screenshots if it helps.

Piyush Nasa said...

What is the condition that you have put in your Custom Action. If it is the same as I mentioned then it should run at repair time as well and change the prefs file again if it has changed already.

Unknown said...

Under Install Exec Sequence
Install Exec COndition = NOT REMOVE~="ALL" OR REINSTALL<>""
I have the Script stored directly in the custom action.

I tried both NOT REMOVE~="ALL" and NOT REMOVE~="ALL" OR REINSTALL<>""

Just to verify, I tried it again and set it to not remove~="ALL" only and same effect. I stupidly didnt enable logs so have to go through the process again. I think I will recreate the process again, I must have step causing this.

Any specific Feature order? Did you run the CA in Deferred or Commit execution? Just to clarify, it definitely runs on repair and then literally last second the prefs get overwritten by something. Not sure if you have tried with 11.0.2 yet. Other then this your directions work great.

Piyush Nasa said...

Yes, Run the CA in Deferred Execution in System Context.
I have not tried with the latest version as of now but it should be the same concept unless they have changed the architecture.
If this still does not work for you. I would suggest you to do it through Active Setup and ask your users to log off and login after the installation. Also make sure that your package should not go for self heal.
In Active Setup create a registry key to run the vbs which you can copy somewhere through your MSI.

Charles Hughes said...

I found this blog entry through a Google search and it is one of the most helpful I have found. I am not an application developer or packager. I do not know VB or understand MSI's very well.

From the information you have provided and the Tuner ultility that is part of AdminStudio 6 I have created an MST to deploy iTunes as I want. It works for the user that does the install but does not work for another user. I accomplished step 2 of your instructions diferently than how you provided. I do not understand Step 3. I have also found your blog entry on "Internal Consistency Evaluators" from July 2012. I believe that if I can get Step 3 implemented, self heal will work for other users.

The tool I am using provides an easy way to add files and registry entries and also provides a way to directly edit the MSI database tables.

I can easily add a registry entry under HKCU for Step 3, but would have to directly edit the registry table to point it to the new component. The new component would have to be manually added to the components table. How would I do those things?

Thanks for any help you or others could provide!

Piyush Nasa said...

Hi Charles, Thanks for appreciating the blog entry.
I would like to know what is the different thing you have implemented in the step 2. Because step 2 is very very important as it is and in the same manner as I have written.
If you could follow the complete insturctions and see if the package works as expected.
In Step 3, you do not need to create any new component. Just see which is the highest (Parent) feature in your application and any component in it which already exists add the registry key and make it keypath.

Charles Hughes said...

I used the Tuner tool from Admin Studio 6. I not have the full AdminStudio suite. The tuner program does not have the ability to create and/or edit custom actions. So trying to do this without creating or modifing custom actions. This is also being deployed to 32-bit XP machines.

What I did for Step 2:
I added to copy the folowing 4 files
AppDataFolder\Apple Computer\iTunes\iTunesPrefs.xml
AppDataFolder\Apple Computer\iTunes\Preferences\com.apple.iTunes.plist
LocalAppDataFolder\Apple Computer\iTunes\cache.db
LocalAppDataFolder\Apple Computer\iTunes\iTunesPrefs.xml

The tuner tool created a cab file with those 4 files in it. I used the direct table editor and added rows in the MoveFile table to copy my mst and the cab file to the iTunes installer cache folder that was already copying the iTunes.msi file. By viewing the various tables, I know that components were created for the 4 files and their folders. Along with the needed entries in the CreateFolder, Directory and File tables.

Thanks!

Piyush Nasa said...

My Suggestion.
No need of move file table. Mo need to add hkcu key.
Rest what you did is fine.
Do this next.
Create a .vbs file with the script above and copy it to your installdir location in your mst.
Create an active setup registry key for your package and the stubpath should point to run the vbs script.
If you do not know about active setup then google it. You will get some good articles.
When you run msi and mst together both will be cached to installer folder by itself so you dont need the move file table.
Active setup will take care of the settings when users will log off and login.

robofruit said...

Hi,

I have ran into the same issue as others whereby the application be it Quicktime 7 or ITunes resets certain default values upon first launch. The key here is to ensure that you DO use a script and not 'Duplicate File', and ensure that it is setup as below...

In the ‘Common Settings’ of the Custom action configure the following...

In-Script Execution= ‘Deferred execution in System Context’
Install Exec Sequence=‘After QuickTimePostInstallMSIProc_deferred’
Install Exec Condition= NOT REMOVE~="ALL"

Otherwise the deferred Quicktime post install will reset your config. Drove me mad this for a day or two.

Unknown said...

Robofruit,

Can you tell us what you setup for the itunes custom action. I saw the custom action you are referring to in Quicktime but I do not see anything similiar to that in iTunes. I put my CA after CheckRebootNeeded and before Launch_iTunesHelper.

The CA is Deferred in SystemContext and exec condition is NOT REMOVE~="ALL". I included the script with the CA. Thanks for the tip on Quicktime, working on that next.

Piyush Nasa said...

Hi David,

I am not sure if you were able to do this or not. I faced similar issue and could understand what you are saying now. It is I think in the new version that this problem arises.
The solution which I have implemented is that you add an active setup key to repair the application at logon. So I agree the first time users log in without rebooting the machine, they will have auto update enabled. But when they log off an log back in, it will be gone.
Another way which you can do it is to run the script after msi install by your deployment tool.

Unknown said...

I may have to try the script after the install and include active setup as well for new users. I am still looking to see if there is a way to include it in the msi, I think it is neater if I can keep it contained. Not to mention I would like to know what changed and why it has this behavior now.

Anonymous said...

Has anyone had success in applying these settings to iTunes 11.1.5.5?

Thanks

Phylum said...

I'm working on packaging iTunes 11.4.0.18 & found this via searching the interwebs. Great post & thank you for sharing.

Do you plan on updating this post, or creating a new post for newer versions of iTunes like 11.4.x?

I'm not some MSI expert and maybe that's part of the problem, but I just wanted to point out that some things are different now than when you first posted.

The latest version doesn't have the following Properties in the Property table: DESKTOP_SHORTCUTS, AMDS_IS_INSTALLED, BONJOUR_IS_INSTALLED, REBOOT, NO_ASUW and NO_BONJOUR.
Although we can easily add them manually, are they still trulyrequired today?

You said:
"Copy these files in C:\ProgramData\Apple Computer\iTunes\ folder in your MST file and then use the below script to run in Custom Action just before InstallFinalize. Condition to be kept as NOT REMOVE~="ALL""

I'm also not clear on how to copy files into the MST file. Did you mean to copy the files into the same directory as the MST so that we could leverage the vbscript?

(I spent some time looking up adding new files to an MST, without using a CAB, and it seems like too much of a hassle.)

Anyway, thanks for the post.

Piyush Nasa said...

Hi Phylum,

I just packaged latest version of iTunes and the steps are still the same.
The properties can be added based on your requirements. For example if you do not want Bonjour then add those properties for Bonjour.
You will need some packaging tool to add files or you will have to script it to add files later to the installation.

Anonymous said...

Hi, Will these same steps work with Itunes 12?

Anonymous said...

What a complicated process.. but a nice challange