Confused about embedding files.

Mar 12, 2009 at 8:32 PM
I am confused about the embedding files features of the product.  It appears to me that the 'package' listed in the MSI component is set up so that the path to the file listed in the entry (#APPPATH\<something>.msi) must match the relative path to the config xml file.  I tried to get around this by creating an embedded file to the path which I want to grab the file and specify the sourcefilepath, but when I do that, I see duplication in the cab file (duplicated with the file listed in the package entry sitting in the same folder as the config.xml.  I know they are being pulled from these locations because I put a different version in both spots). 

My goal is to integrate this into a build process where our msi is stored in one location and the prerequisites may be picked up from a different location.  In looking at the documentation, it seems like this should be possible, but I am just not getting it to work right.  The documentation states, "Ensure that your dependency files are embedded. This is not automatic except for Embed File components, msi components and components with a Download File subcomponent."  It appears to me that if I do not use the /e from the command line (or check the box in the UI) that even the files that I am setting to embed are not making into the .exe file.

Please let me know if I am missing something.  This product appears to be a great solution to a big problem that we have.

Thanks for your time!
Coordinator
Mar 13, 2009 at 12:37 PM
You're right about the MSI component embedding the file under the same relative path. And if you use another explicit EmbedFile it will add two files (one from the MSI component, another from EmbedFile).

I am understanding this correctly that you simply want to be able to disable automatic embedding for the MSI component? This is really easy to implement. I filed http://dotnetinstaller.codeplex.com/WorkItem/View.aspx?WorkItemId=2107.
Mar 13, 2009 at 1:40 PM
Yes, that would be great.  Thanks for all of your work on this project. 
Coordinator
Mar 13, 2009 at 3:46 PM
I checked in the code and uploaded a build.
http://dotnetinstaller.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=23955
There're new embed boolean options.
Mar 30, 2009 at 3:57 PM
I am really confused about embedding files too. I am using the linker and my problem is that I can't get my application MSI to embed no matter what I do it seems.

Maybe my mental model of how this works is off somewhere.

1) given the xml below...

<component package="#CABPATH\Application.msi" type="msi" embed="False" ... >
      <embedfile sourcefilepath="bin\Release\Application.msi" targetfilepath="#CABPATH\Application.msi" />
</component>

I would expect this to mean that the Application.msi file to embed is found in the bin/Release subdirectory of the directory where the configuration.xml file is located at link time, or at least relative to the "current directory" used when shelling to InstallerLinker.exe from NAnt.

I would also expect it to mean that if the file is successfully embedded in the bootstrapper's CAB file, it will be found when the installer executes (since package and targetfilepath match).

Am I assuming the right things here?

2) If I instead use embed="True" and remove the embedfile-element, how do I specify where InstallerLinker.exe will find the MSI to be embedded? Or where does the linker look?

3) when I use embed="False" and instead try to explicitly pass EmbedFile:[path to msi], the linker complains with the following error message:

ERROR: Value can not be null.
Parameter name: path1

I assume this means the linker can't find the file? The MSI file is there, but it obviously does not work.

BTW, if I got this right, shouldn't the linker complain when I use the embedfile-element, but the linker ends up not embedding any file?

(I'm using 1.6.19882.0)

PS. Expecting the app msi to be found using a path relative to where dotNetInstaller.exe is located before linking (?) seems unnatural to me, but also somewhat confusing ("APPPATH - The folder from which the setup bootstrapper is executed." - this makes no sense, what path is this when executing the linker).
Coordinator
Mar 30, 2009 at 11:46 PM
Okay, I'd like to unconfuse people in 1.6 with more code changes and better documentation.
  1. I am going to remove the component-based option embed altogether. That means that there's nothing automatic or magical happening in the embedding process. Too bad if it breaks backwards compatibility, it's just too confusing to everyone unless it's something explicit. So just forget about that option for now, set it to false in your config until there's a new build.
  2. You need EmbedFile components for every file you want to embed. An EmbedFile has two parameters: source and target. The source is the location relative to /AppPath. That might be confusing because of the name "AppPath", but this is the location that is prepended source. target is a relative path at runtime where this file is extracted.
  3. /EmbedFile:path should work without the error, it looks just like a bug to me. I'll check that out.
  4. I agree that /AppPath should have nothing to do with dotNetInstaller.exe before linking. It shouldn't be this way, meaning that by default it should probably just be the current directory?

Anything else? Thoughts?

Thx
dB.

Mar 31, 2009 at 8:03 AM
That sounds like a really good direction to take. Simple and explicit is better.

One thing that bugged the heck out of me was the combination of embed="True" for a component that had a downloaddialog. This made me feel very uneasy and doubt my understanding of the whole thing. If I want the bootstrapper to download the file, then embed what? :) In my mental model, embed means embed into bootstrapper exe, and not some temporary CAB file that is created as that bootstrapper is executed and doing its thing (if that's what it means, I still have no idea).

There is one other thing I don't understand. Assuming I use an explicit embedfile element in my config to embed my app MSI. When I run the linker it builds a bootstrapper without the MSI embedded into the bootstrapper. Why is there no error message in this case? If there would be, I would know that when the linker runs without problem it actually produces what the config says.

If you don't like the idea of an error message halting progress, how about a warning. It would REALLY help. Especially if the message was displaying the full path of where the linker is trying to find the file that is not embedding. This is my biggest problem right now and I still have no idea what I'm doing wrong. Since there is zero feedback from the tool I feel I'm stuck with trial and error.
Coordinator
Mar 31, 2009 at 11:30 AM
Makes sense. The reason why we require /Embed to enable embedding is for building dual configuration bootstrappers and to enable quicker debugging. With automatic embedding gone, this option makes less sense in it's "false" default. I'll switch it to true and you will just be able to disable embedding with /Embed-. Therefore it won't need any additional warnings.

Will show missing files, this is trivial. I realize that the list of files is dumped, but nothing tells you which full path is missing.

For some background, people use disabled embedding a lot for large bootstrappers. Instead of packaging the whole thing I just run InstallerLinker without /Embed and put things in a staging folder as if the bootstrapper was expanded. This is a lot faster for debugging.
Mar 31, 2009 at 12:08 PM
YEEEES!!! Adding just /Embed on the command line seems to have fixed my problem!

I had to read your post like three times to understand that you meant just that switch by itself and not followed by anything. I'd tried versions of /EmbedFile:blah and so on, to no avail. Maybe I've been thick headed, but I've poured through the help several times and obviously missed completely that it was required to activate embedding.

ps. The bug about EmbedFile might be that passing EmbedFile does not implicitly activate Embed, cause I sure never passed both.

Thanks!
Coordinator
Mar 31, 2009 at 1:06 PM
You're definitely not thick-headed. You're probably the 10th person to tell me how confusing this is. So I am glad to make changes to unconfuse users. Here're all the changes in the new build 1.6.20737.0 that I uploaded to http://dotnetinstaller.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=23955.

  • Changed behavior of file embedding to explicit: disabled automatic embedding of files from msi, download and openfile components, set /Embed to True by default.
  • Added an EmbedFolder configuration component to embed directories and subdirectories with an optional wildcard and configurable destination.
  • Added parity between EmbedFolder and EmbedFile components which can be now specified in both the configuration and on the command line.
  • InstallerLinker: embedded files that cannot be found are reported as errors with their full paths.
  • InstallerLinker: Changed default value of /AppPath, now defaults to the current directory and not to the location of the configuration.xml.

Please pickup the new build and give it a shot. Also do read the updated CHM's single packaged setup tutorial. Reply with your comments/problems.

Thanks,
dB.

Apr 8, 2009 at 8:09 PM
Edited Apr 8, 2009 at 9:00 PM

Hi,

those new features sound pretty good and I am playing currently around with it. Unfortuneately is it somehow not possible for me to embed files with the EmbedFile, EmbedFolder Component nor the linker switches. To me it is not clear (even after reading the manual ;) ) to what the inserted path is relative.

If I have a config File "config.xml" which is placed in "c:\test\setup\" and have all the DNI stuff in "c:\test\setup\dni" what should I insert in the "source" text box of an input file comonent if I want to insert a "install.msi" into the resulting exe?
And can it be made possible to make it somehow again relative to where the configuration file is located? The problem I have is that I edit the configuration with the DNI editor but in normal build process I have a msbuild script which calls the DNI linker directly. The problem is that the MSBuild file is at a different location then the DNI editor. Consequently needs the EbedFile source path be not relative to the one or the other.

Thanks,
Tom

Edit:  Finally, I figured it out. Now I use "#AppPath\..\install.msi" (without quotes) as the source and the MSBuild call to the linker sets the AppPath to the editor direcotory and now it works - great :)

Coordinator
Apr 8, 2009 at 9:56 PM
Re-read the latest docs. Is there something I should change?
Apr 12, 2009 at 9:55 PM
No, there is nothing you should change. I don't know why it was not working our why I was working in a wrong diraction. At least do I have this impression after re-reading the docs :)