File Versioning Rules When Neither Components Has a Key File - installation

According to URLs I referenced, I understand that the Windows Installer uses key files to compare the version, date, and language of components and determine whether to update the component on target machine.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa368599%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa371221%28v=vs.85%29.aspx
I also understand that default versining rules consist of 4 different cases as listed below.
Both Files Have a Version
Neither File Has a Version
Neither File Has a Version with File Hash Check
One File Has a Version
What I don't understand is that how does the installer determine whether the component needs to be updated if neither components has a key file?
And what's going to happen if neither components has a key file, but a file on the target computer indicates that its Modified date is later than the Create date? In this case, even when both products have a version, are they going to be considered as having Non-versioned files because no key file is set to components? How does the installer determine whether to install?
Any answers would be really appreciated,

Every component from the installer must have a key member, this is imposed by Windows Installer to build a valid MSI package. Also, Microsoft strongly recommends that you create independent components for each DLL, EXE, OCX and hlp/help file. This will allow the file versioning rules to be correctly applied.

Related

Adding an external CAB to an MSI with an internal one

I have a visual studio installer (vs2015) that installs an application. I want it to also install a set of configuration files, the contents of which vary by physical install location, that will be delivered as a cab file in the same directory as the msi. The cab has a known set of files that will be distributed across 2 folders in the install location and is created by a different project than the installer. How do I get the msi to install both its internal contents and the contents of the external cabinet file?
Wise Package Studio
I actually successfully updated MSI files with new files to install using Wise Package Studio back in the day. It added a CAB file to the Cabs table (I don't know if this table is actually a Wise "view" or a real MSI table - it seems missing from Orca if all CABs are embedded in the MSI). There is a corresponding entry in the Media table where the LastSequence value (in the Media table) describes which CAB contains what files. In the File table you will find a field called Sequence which specifies the "order" of the files listed. Essentially your new files will be at the end of the "order" and hence in a new CAB. A bit involved the whole thing.
However, I successfully got Wise Package Studio to both embed a new CAB file, and to use an external CAB file to install the new files during installation, but I don't have the procedure documented and don't recall all the steps. Moreover I don't recommend the procedure - in fact I would never use this approach now. It was just used at the place I worked at the time. In most cases we used a transform to add this content to the main package, rather than hacking the MSI itself.
MSI SDK: Including a Cabinet File in an Installation
The procedure to add a CAB file to your MSI is documented in the MSI SDK here: Including a Cabinet File in an Installation. Quite involved - as I said, but definitely possible. As you will see the lack of a # flag at the start of the CAB name in the Media table indicates an external CAB file.
So I suppose, in short:
Add a new entry to the file table, set the Sequence number to +1 from the highest sequence File entry already there. I would add a new, corresponding entry in the Component table as well.
Add a new row to the Media table, specify the number you set for the file in the LastSequence column. Add the name of your cabinet file to Cabinet. Make sure to not prefix the CAB name with #.
Wise would also add entries in the MsiFileHash table. Not sure if this is required or not. Pretty sure it is not required to add entries here.
As you will see in the linked MSI SDK article, you can embed the whole cab following the last few steps listed in the linked MSDN content.
I wish I had time to test all this, but I don't. Which brings me to the next point:
Default / Instantiate Your Settings?
When I see questions like these I invariably ask myself: what is in these files? Are they "trivial settings" that could actually be defaulted instead of hard coded in config files? This has saved me a lot of work, many times.
The deployment of settings and data files have always been problematic with both MSI and legacy style installers. My philosophy of deployment for such files is to treat what you install as "read-only" and then you copy them to per-user locations or set them in HKCU on application launch, using some sane process of obtaining appropriate values (from settings written to HKLM during installation, retrieved from the user, retrieved from the Internet, etc...). Please see this longer answer on the subject: Create folder and file on Current user profile, from Admin Profile. The best approach, in my opinion, is to retrieve settings on launch from an online database (as you will see if you read that linked content), but that is involved.
It's not clear precisely what you mean, but you cannot alter the MSI to unpack all the files in your separate CAB as if they were in the MSI as the other files are. There is too much internal data on the files inside the MSI file, in the file table, component table, and so on.
So if the CAB file is in the same location as the MSI file then you could create a custom action to copy it to the target system, and unpack if you want. The copy can be told where the MSI location is by using the [SourceDir] property or the [OriginalDatabase] property OriginalDatabase property
You'd parse that location to get the path and then do the copy to the TARGETDIR location.

vsdraCOM causes the codebase path to point to build path

We have a couple of dlls we like to install using an msi.
In our test environment, we are using regasm -codebase to register the dlls.
As I understand from googling, this is accompliched in an msi project by setting the register property to vsdraCOM.
The problem is that when we run the installer and checks the registry, the codebase path is set to the path the file were in when building the msi.
I'm going to expand on Hans' answer and that link info, and it may be more than a comment can hold.
That reg file will contain the path to the file and the link article recommends using [TARGETDIR], which is basically wrong if the file is not being installed to the application folder. The path to your file should be written as [#file-key] in the reg file that you import. In a VS setup project the file-key will be (just an example) something like _B049230C37DE4B6787C578DCEE30252A. Open your MSI file with Orca, go to the File Table and use the file key in the File column that corresponds to your file name.
That comes from here:
http://msdn.microsoft.com/en-us/library/aa368609%28v=vs.85%29.aspx
the 7th bullet point. It resolves to the file path wherever it is installed to.
The other thing that can be done is to let Visual Studio do its incorrect thing, then go to the Registry table with Orca, find the path and put that [#file key] in it such as [#_B049230C37DE4B6787C578DCEE30252A] and people sometimes do those kinds of updates with a post build script to update the MSI.
None of these are great, but they should work and get you out of using the GAC. VS setup projects really should be using that [#file key] syntax, and it's just a silly bug I assume.
Speaking as someone who's made a full time living writing installs for 18 years, my first suggestion would be to switch to Windows Installer XML. If you insist on using .VDPROJ, I would suggest reading: Redemption of Visual Studio Deployment Projects.
The concept is you use Windows Installer XML to create a merge module and then consume that merge module with .VDPROJ. In Wix, you use Heat to harvest the DLL. It will extract the COM / Regasm metadata and author it as Registry table entries. This provides a nice clean encapsulation using authoring best practices and avoids the need to do any post build hacking of the built MSI database.

Perforce: How to automatically check out binary when source gets compiled

I would like to create a mechanism by which I automatically submit the executable corresponding to the updated code. My development environment is Visual Studio 2005 and I use the windows GUI client to submit changes.
Ideally, I would like to ensure latest binary is submitted in the same change list as the code changes.
My requirements are:
The code should be recompiled and binary should be checked out when source code dependencies change.
Related documentation / non-source files do not affect binary
Perforce should complain when sources are changed and submitted but the binary isn't included in the change list.
How could I enforce these rules? Is it possible to create a P4 script that runs before each submission? Also, is it possible to write a Visual Studio script that automatically checks out the executable before compiling?
Thanks,
Shahar
I think you can accomplish most of this without too much work.
If you include the output directories in your Perforce workspace, you can easily just check them in every time you do a build. (You might want to talk to the Perforce admin about using a 'purge' option so you're not storing thousands of copies of binaries.) You can use a trigger to make sure that source code in certain directories is always submitted with a binary.

MSP file extracts only files that belong to new components

I've created a patch with Advanced Installer by using an old (target image) msi and the new one (upgrade image). Inspecting MSP file I've discovered that it contains both modified and completely new files. The problem is that during the installation it installs only the "added" files. Existing files are ignored. I've already tried MSIEXEC switches like:
REINSTALL=ALL
REINSTALLMODE=sumo / aums / omus etc...
UPGRADE="Yes"
IS_MINOR_UPGRADE = "1"
..in different order and combinations (i.e. "REINSTALLMODE=aums REINSTALL=ALL"), so don't reply or comment just by telling me to try REINSTALLMODE=omus or something similar.
When creating a patch there is a set of rules that need to be followed, have you checked those? Breaking one of those can lead to unexpected behavior, such as the one you are now encountering.
To check for the rules you can start with a diff between the project files, as they are standard XML ones, and check for their product code, component GUIDs, etc... For example folder synchronization is a common problem encountered when a patch is created, as this changes the component GUIDs.
For some odd reason all the core components (exe, dlls) I wanted to update were set to "Do not register this component with Windows Installer".
I suppose this is some kind of project bug, because it's very old and was migrated through different Advanced Installer versions (7, 8 and 9).
Anyway, I was not able to update my application correctly even with a fixed patch. Windows Installer kept on asking me to browse to target image msi file (cached installer of the previous version).
However not all of my customers keep those files (usually this cached files are stored in %APPDATA% folder). So I found a workaround:
I've applied "Hash files" option in order to create a MsiFileHash table
I've packed my msp patch in a bootstrapper (exe file) that starts it with the TWICE with following command-line parameters:
first time:
"myPatch.msp" /n {150F6CE2-8C12-414B-9377-F087A62E6B67} REINSTALLMODE=c /qb
second time:
"myPatch.msp" /n {150F6CE2-8C12-414B-9377-F087A62E6B67} REINSTALLMODE=dep /qb
REINSTALLMODE=c switch forces file compare algorithm based on hashes, so it doesn't require the original setup sources anymore
REINSTALLMODE=dep restores all the other missing files, files with unknown or different (from target) version
I hope this workaround will be useful to people that use MSI/MSP authoring tools other than Advanced Installer

Visual Studio: different ocx file version number for new OS?

I'm looking for general advice. I created a Visual Studio 2010 project that outputs an ocx file that is used on XP and Vista machines. The DLL on which it depends has been updated on our Win7 machines. I simply needed to rebuild for Win7 using the exact same code with an updated .lib file. I created a second project configuration (ReleaseW7) and it only differs from the original project config (Release) in that it points to the new .lib.
So now I have 2 files both named xx.ocx. Besides looking at the name of the folder each file resides in (or looking at the creation time of each) there is no way to determine which is which. I thought of using different file version numbers but as far as I can tell (and I'm relatively new to this so I could certainly be wrong) that would require two separate projects each with a slightly modified resource (.rc) file, instead of simply having two configurations within the same project. If nothing more, that seems like a waste of hard drive space. It also feels like the "wrong" way of using file version numbers
Is there a cleaner or more "standard" way of handling this? All I really want is a way for the folks who install the ocx and support the end user to know for certain that they are working with the correct file.
Long story short, I decided to use different version numbers. I was able to setup a preprocessor definition for the resource compiler and use that to handle different versions of VS_VERSION_INFO in my .rc file.
In case anyone is interested, this is the resource I found:
http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/605275c0-3001-45d2-b6c1-652326ca5340/

Resources