Windows cabinet file for sub directories - windows

I've a java project which has set of libraries and xml files in separate directories. But when I see cabinet file which I created it has all the files in one place (with out sub directories though I can see files). Can I create a cabinet file which includes sub folders?
If it is not possible to include directories in cabinet file, once I release cabinet file to my end user for his installation then should I need to provide INF file to him along with cabinet file?
Can any one provide sample INF file for this problem?
What is the immediate step an end user will perform once he receive cabinet file? Will he open it with IE?

To answer your first question: Yes cabints do support directores. See this blog post for example. If you use makecab as tool you can create a directive file which controls which files are zipped and into which directories (may be different ones) they are extracted.
Example:
C:\temp>type files.txt
C:\temp\test1\files.txt
.Set DestinationDir=TestDir1
C:\temp\test1\test2\2.txt
.Set DestinationDir=TestDir2
C:\temp\test1\test3\2.txt
With the following command I could create the cab file
makecab /d "CabinetName1=test.cab" /f files.txt
When I open the cab with 7-Zip I can see that the file 2.txt will go to TestDir1 and TestDir2 as expected. That said why do you bother with a cab file? I your application does not need an installer you could use a zip file with much less hassle.
But if you need to create some installer I would recommend to use the WIX toolkit where you "only" need to declare what gets installed to which location in an xml file. For more infos please consult the manual. The WIX toolkit also creates the cab files needed by msi for you.
You want to distribute a java application which may be largely OS independant but the installer, if you need one, is not. Please use for each target platform the preferred installation mechanism to ensure the least amount of problems to your customers.
Yes I know this advice sucks. But deployment is also an important development activity which always was (and I fear always will be) much more complex and error prone than one might initially hope.

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.

NSIS installer fails to find existing files while compiling

So I have been trying to build an installer for my game with NSIS. For the most part it works fine but just noticed that it seems to be skipping certain files for no reason. Or no reason I can figure out.
At first I was using this line to gather up all the files in the source folder:
File /r "${NSISDIR}\game\source\*.*"
However, I noticed that this didn't get everything. Granted it found all sub-folders and kept the hierarchy correct. There didn't seem to be any rhyme or reason to what it skipped. Then I tried listing all files and directories separately and found out why. Example:
File "${NSISDIR}\OWTD-DE\source\pygame.math.pyd"
This produces the following error:
File: "C:\Program Files (x86)\NSIS\game\source\pygame.math.pyd" -> no files found.
But that file exists, I can see it in the source folder. This was the case for all missing files. At first I thought it may be the two periods in the name, but various files have that naming convention and they are added fine. I cannot figure out how to get it to recognize these files. Any ideas?
${NSISDIR} is a define used to access the UI resources in the Contrib subfolder, you are not supposed to put your files there. Your source files should not be in Program Files, only installed files should be located there. Also, on 64-bit systems there are two Program Files folders and there are some compatibility hacks in Windows related to %ProgramFiles% so putting your source files there is not optimal. Just because you see that file there does not mean it is actually in Program Files, it could be UAC Virtualization/VirtualStore tricking you...
Normally you would keep your .nsi somewhere in the same directory tree as the rest of your files so you can use relative paths but you can also use a define if you really want to:
!define MYSOURCE "c:\foo\bar"
...
Section
File /r "${MYSOURCE}\*.*"
SectionEnd
If it still misses some files I would suggest trying Process Monitor so you can see the low-level details...
Weirdly enough, this process did not work very well on Windows Home 64-Bit but did on Windows Professional 64-Bit. I'm not sure if this an issue with NSIS itself or what, but nothing was different between the two except the OS. And there really isn't much difference between those two operating systems. However, perhaps some configuration differences between the two was the real issue.
While marked solved, I'm not really sure what the actual issue and solution could be.

How to make WIX create files to Program Files folder in the installation? I have "Access defined"

I am creating a WIX installer project. During one managed customized action, I need to create a file (other than the deployed files specified in the components of WIX) in the installation folder, which by default is the Program Files folder. I am experiencing the "Access denied" problem in Windows 7. After some searching, I found out that people say it is not advisable to create files into Program Files folder. Instead, try to create files into for example AppData folder. For example, see this link:
C# Access denied to path in a Windows Application
But my question is, the generated file is crucial to our SW, so it must reside in the installation folder. Isn't it the target of SW installation, I mean, to create file in most of the cases Program Files folder? Does it mean the only files should be added into installation folder, during the installation, are the deployed files (basically the targets of XCopy)?
My file can't be made deploy-able in the WIX, i.e, it can't be made ready before the installation. So what's the proper way or best practice to handle such situation: a file must be generated during the installation, into the installation folder. It is not some log file that I can put somewhere else. I tried to create a Permission element in WIX for the INSTALLADIR, although it seems to be against the rule mentioned in the link, but it still failed. Thanks!
UPDATE:
Based one MichaelUrman's commen, some more information. The generated file is needed after the SW is installed and necessary during normal launch of the SW. And I think it needs to be modified during normal use after the installation. And as I mentioned my a comment to #caveman_dick answer, my CA is actually in commit phase, I don't know whether there is any difference between it and normal deferred CA
Set the custom action to Execute="deferred", that will run the command elevated and should give it the required permissions to create the file.
Since you need to update that file from the main application, and I'm assuming your application does not require elevated privileges, you have three options.
The first is the worst: without a manifest, your executable's attempts to write to the Program Files folder will typically result in it being redirected to the Virtual Store (see File Virtualization). It sounds like this isn't happening in your case, so you can't use it.
The second option is to modify the application to store this in an appropriate location such as the ProgramData folder, or Common Documents, or (if appropriate) a per-user location under LocalAppData. This is typically the best approach, but has the highest development costs.
Finally the third option is to create the file and change its permissions (or in some cases to change the permissions on the folder containing the file), allowing limited users to modify this file. See LockPermissions or MsiLockPermissionsEx for the Windows Installer way to approach this. Change the permissions on as few files or folders, as restricted as possible, to keep the system as safe as possible if you go with this option.

How to create a single file installer to place a .ocx file in the System32 folder and register it?

I have looked everywhere and cannot find any simple solution to this. It must be a single file installer.
I had created it with a simple 2 line batch file
copy .\Files\WGMX.ocx C:\Windows\System32\
C:\Windows\System32\regsvr32.exe /s wgmx.ocx
But translating this simple 2 line batch file into any of the installer helpers I have used has been an incredible nightmare. Any help would be appreciated.
Assuming you want a normal MSI package, this can be done very easy with the free version of Advanced Installer. Just create a new "Simple" project, i.e. the free one, go to Files and Folders page and add your OCX files, than double click it and go to Registration tab, so enable the desire settings.
Very important, if you want the same file in "System32" folder on x64 machines you need to create a separate MSI, with the installation type set to AMD64, option available in Install Parameters page.

Freeware tool for creating a single file installer from an msi file + config file (thats easy enough for an End-User to use)

My installer requires there be two files in the same directory in order for it to install.
The installer (.msi file)
An organization specific config file that the installer copies. (This file is customized by the organization and then distributed to it's end users).
Since there are two files, the file has to be distributed as a zip file. Which presents the issue of if a user tries running the .msi without actually extracting the zip... only the msi file gets extracted. I am able to detect the issue in the install process and tell the user they need to unzip the file... but you know how noone actually reads error messages.
So, I'd like to make it more foolproof and so i was wondering if there was a simple tool that i could let my customers (ie the organization) be able to make modifications to the config file and when finished create a .exe file which when clicked would extract to a temp folder and then run the msi. I know there are solutions for this which require commercial software. I'm wondering if a simple freeware tool exists that can do this.
Edit: Accepted Solution Notes:
The one issue i ran into is the iexpress wasn't designed to be used for .msi files. As a result on the step that asks you for the Install Program. It's a combo box which if you had added a .exe file in the previous step could just select the .exe file from. Instead you have to manually type in
msiexec /i yourinstaller.msi
I was very pleased to find such a simple solution that's built in to windows. The only way this could be better is if it allowed for wildcards so that your iexpress project would be able to handle changes in the msi file's name which occur with each version. And defaulting the Install Program to the .msi file. These minor inconveniences are offset by the fact that end user wouldn't need to install any new software to create the package so I have stopped looking for other tools.
You could try using iexpress.
It enables you to package up a set of files which can be extracted, with the option of running an installation command automatically after extraction. It also has options to enable you to prompt users about things, show a EULA, restart the computer, etc..
I believe it comes as part of Windows (part of IE?) - try running iexpress.exe from the run dialog to get the UI.
The Wix project has a bootstrapper and packager for dealing with this kind of thing.
I've used wix a lot but haven't really looked at the bootstrapper/packager much - last time I had a quick look it wasn't really usable but that was a long time ago so it may be better now.
I'm guessing that the config file is something like a properties file, and that you want users to set the values of the properties "foo" and "bar". You don't need a separate tool to update the file.
I would do this:
Put one or more dialogs in the install that ask the user what the values of foo and bar should be, and set a couple public properties accordingly.
Write a custom action that writes the config file out to whatever location you want, including whatever values you want for foo and bar. This would be pretty easy in vbscript.
Put the custom action somewhere in the execute sequence (ideally as a deferred execution action, since you're making changes to the system).
Add an entry to the RemoveFile table, so the config file is removed on uninstall (assuming you don't want it to be left behind.)
Add an entry to the LaunchCondition table, to prevent users from doing a silent install. Or if you want silent install to be allowed, make the names of the public properties that hold the config data known, and make them part of the LaunchCondition. You would block "msiexec /i myapp.msi", but you could choose to allow "msiexec /i myapp.msi FOO=Something BAR=SomethingElse".

Resources