Installer Auto Run

  • Thread starter Thread starter Thom Little
  • Start date Start date
Ed Courtenay said:
Maybe you'd find the Windows Installer XML (WiX) toolset useful:

http://sourceforge.net/projects/wix/

From the SourceForge page:

"The Windows Installer XML (WiX) is a toolset that builds Windows
installation packages from XML source code. The toolset supports a command
line environment that developers may integrate into their build processes to
build MSI and MSM setup packages."

This is a Microsoft released project that's been made available via
SourceForge; a blog detailing more information can be found here:
http://blogs.msdn.com/robmen/category/4625.aspx

Aha - great, thanks very much. I'd heard about WiX on Slashdot, but
hadn't investigated what it actually was...
 
I've solved it in a pretty foul way in the end, but it works: the
installer will have the name of the product as its main window title. I
just search for any msiexec.exe processes with that main window title,
and wait for them to exit. Nasty, but it seems to work.

Sometimes nasty is about the only way to get it done in a reasonable period
of time.
Cheers for your ideas though.
Thanks.

Do you use custom actions in your installed assembly? If you do, and if you
use auto-uninstall when doing an upgrade to a newer version, then I ran into
a nasty windows installer bug today that might affect you. If you don't then
I wont bore you with the details.

Dave
 
Jon Skeet said:
Aha - great, thanks very much. I'd heard about WiX on Slashdot, but
hadn't investigated what it actually was...
If you do have the time to investigate I'd be curious about what you think
about it. I've tried to stick with the builtin .net wizards but there's
usually some wall that you can't get beyond without digging into it a whole
lot further then I'd really like to (and the documentation is weak). MSI
files and the windows installer are a LOT more complicated then just a bunch
of text files strung together.

Dave
 
Dave said:
Sometimes nasty is about the only way to get it done in a reasonable period
of time.

True, unfortunately.
Thanks.

Do you use custom actions in your installed assembly? If you do, and if you
use auto-uninstall when doing an upgrade to a newer version, then I ran into
a nasty windows installer bug today that might affect you. If you don't then
I wont bore you with the details.

I use custom actions which are in an assembly on their own, rather than
in anything used by the rest of the application. The only custom action
in the uninstaller is something to remove registry entries - in the
case of an upgrade, it doesn't matter too much whether or not that
happens.

If it's still something I might run into, please let me know!
 
Dave said:
If you do have the time to investigate I'd be curious about what you think
about it. I've tried to stick with the builtin .net wizards but there's
usually some wall that you can't get beyond without digging into it a whole
lot further then I'd really like to (and the documentation is weak). MSI
files and the windows installer are a LOT more complicated then just a bunch
of text files strung together.

Well, initial reaction after decompiling my pretty simple installer is
that I'll definitely need a lot more than the WiX documentation in
order to get going. I might try to build up some knowledge with a
"build installer in VS.NET, decompile, add a bit, rinse and repeat"
approach, but that'll only get me so far. Without guidance on what is
not only *allowed* where but what is likely to *work* where, I'm not
sure I'd feel comfortable using WiX. As WiX gets more community
involvement, however, I'm sure the documentation will get better and
better.
 
Jon Skeet said:
Unfortunately finding a parent process is easier said than done - it
would require P/Invoking undocumented methods, which might be different
for different operating systems. Horrible.

No Pinvoke required, just use System.Management...

using System.Management;
.....
int parentPid = GetParentProcess(Process.GetCurrentProcess().Id);
......

static int GetParentProcess(int Id)
{
int parentPid;
using(ManagementObject mo = new ManagementObject("win32_process.handle='"
+ Id.ToString() + "'"))
{
mo.Get();
parentPid = Convert.ToInt32(mo["ParentProcessId"]);
}
return parentPid;
}

Willy.
 
I use custom actions which are in an assembly on their own, rather than
in anything used by the rest of the application. The only custom action
in the uninstaller is something to remove registry entries - in the
case of an upgrade, it doesn't matter too much whether or not that
happens.

If it's still something I might run into, please let me know!
From what I've seen so far (and I'm still investigating) it appears that
windows installer creates a single appdomain and runs all the managed code
within that appdomain. This is normally not an issue, but when doing an
automatic uninstall/install it appears that it never recycles the appdomain.
The consequence is that even though the assembly on disk that contains the
custom action has been replaced with a newer version, the version of the
assembly that windows installer calls into to run the custom action is the
old assembly that should have been deleted and replaced with a newer
version.

I'm hedging by using "appears" etc. because I'm not precisely sure what it's
doing, but it does look like this is what is happening. I added diagnostic
code to the custom installer that dumped the assembly version that was
executing, and the old version number showed up when running the install
custom action.

I consider this to be a *major* flaw in their implementation.

It also implies that if you get the process id at the time your custom
action executes then you may not need to get the process id of the parent -
it may be the same process. I haven't checked that out yet but I will do
that later today. I will write a simple app with a custom installer action
that just dumps out all the appdomain and process related data.

Dave
 
From what I've seen so far (and I'm still investigating) it appears that
windows installer creates a single appdomain and runs all the managed code
within that appdomain. This is normally not an issue, but when doing an
automatic uninstall/install it appears that it never recycles the appdomain.
The consequence is that even though the assembly on disk that contains the
custom action has been replaced with a newer version, the version of the
assembly that windows installer calls into to run the custom action is the
old assembly that should have been deleted and replaced with a newer
version.

Interesting. I'd hope for the old assembly to be used for uninstall and
the new one for install. I'll investigate myself and let you know
whether I see the same effect. I'll let you know - and thanks for the
heads-up.
I consider this to be a *major* flaw in their implementation.

It also implies that if you get the process id at the time your custom
action executes then you may not need to get the process id of the parent -
it may be the same process.

It's not, unfortunately - I assumed it would be, and ran into
problems...
 
Willy Denoyette said:
No Pinvoke required, just use System.Management...

<snip>

Ah, lovely thanks - but what platforms will that work on? I suspect
I'll stick with the grotty hack for the moment, but I'll keep that
snippet for a time when I really, really need the parent process :)
 
Runs on me, XP, W2K, W2K3 out of the box.
Win98se and NT4 needs the WMI core redistributable installed.

Willy.
 
Interesting. I'd hope for the old assembly to be used for uninstall and
the new one for install. I'll investigate myself and let you know
whether I see the same effect. I'll let you know - and thanks for the
heads-up.

I did some more checking today and confirmed the problem; I opened an
incident with MSFT about this. They may already be aware of the problem, and
I may have given them more credit then they deserve - the problem may be
much dumber then my hypothesis :-). I just read on another newsgroup (where
I posted a query) that they will only load a DLL once, so it may not even be
related to appdomain recycling.

The means that I cannot use auto-uninstall/install for my app - too many
things will not work correctly if the wrong assembly is loaded during
installation. We do major things at install time, like generate dynamic
assemblies from types in the assembly, upgrade databases, install security
code groups, generate cache files, etc.

I'll let you know what I find out from MSFT.

Dave
 
Dave said:
The means that I cannot use auto-uninstall/install for my app - too many
things will not work correctly if the wrong assembly is loaded during
installation. We do major things at install time, like generate dynamic
assemblies from types in the assembly, upgrade databases, install security
code groups, generate cache files, etc.

Could you fix it by putting the version number in the *name* of the
assembly containing install actions? Bit of a pain to say the least,
but it might work...
 
Could you fix it by putting the version number in the *name* of the
assembly containing install actions? Bit of a pain to say the least,
but it might work...
Yah, that would definitely be a pain all right. It would probably work
technically but I think it would cause more problems then it would cure.

We'd have to change the name of the assembly for every release build. I use
an fully automated build system, so I'd need to rewrite my build program to
automatically calculate an assembly name based on the version, and then
modify the project file configuration so that not only would that assembly
name change, but all assemblies that reference it would also need to change
as well as all custom actions that refer to that assembly. And then update
all the documentation that contains the name of the assembly. And then try
to explain why we are doing this to everyone....technical people, salesmen,
and customers.

I think I'll wait for MSFT to fix this :-)

Cheers,
Dave
 
Dave said:
Yah, that would definitely be a pain all right. It would probably work
technically but I think it would cause more problems then it would cure.

We'd have to change the name of the assembly for every release build. I use
an fully automated build system, so I'd need to rewrite my build program to
automatically calculate an assembly name based on the version, and then
modify the project file configuration so that not only would that assembly
name change, but all assemblies that reference it would also need to change
as well as all custom actions that refer to that assembly. And then update
all the documentation that contains the name of the assembly. And then try
to explain why we are doing this to everyone....technical people, salesmen,
and customers.

Gosh - how much stuff do you have going on in that assembly? Is it an
assembly which is used for other things than installation? For our
installation, we've got an assembly which contains installation actions
and *nothing* else - so there's no need to really document it etc, and
nothing references it.

Use NAnt to build that one assembly, with appropriate properties, and
I'd think you'd be done.

I agree it's still a pain though - and if your setup is somewhat
different to ours, I can understand your reluctance :)
 
Gosh - how much stuff do you have going on in that assembly? Is it an
assembly which is used for other things than installation? For our
installation, we've got an assembly which contains installation actions
and *nothing* else - so there's no need to really document it etc, and
nothing references it.

It's pretty complicated. Perhaps in retrospect I should have put it in its
own assembly but at the time it made sense to put the code that called
private/internal methods in the same assembly. It also started as something
small and simple that grew over time (evolution is never pretty). The
assembly that is called by the custom action is actually the web service
assembly. All the types that the client application uses are defined in this
assembly (exported to the client side via a proxy dll), and the
installation/upgrade process directly accesses these classes as well as
calling database code. The custom action does a lot more then just database
upgrades, but that is one of the major chores.

I could move the functionality into a separate assembly but it would be a
PITA. On a new project I would start with that.
Use NAnt to build that one assembly, with appropriate properties, and
I'd think you'd be done.

My build program uses the DevStudio automation object to drive the build
process. What I like about that is that I do not have to worry about
dependencies, build order, etc. as the solution itself handles all that.
Anyone can change whatever they like in the solution (new projects,
refactoring, etc) and the build program does not need to change at all
(usually). I suppose I'll have to port over to MSBuild someday...

I agree it's still a pain though - and if your setup is somewhat
different to ours, I can understand your reluctance :)
Yah, it's pretty different :-)
 
Dave said:
It's pretty complicated. Perhaps in retrospect I should have put it in its
own assembly but at the time it made sense to put the code that called
private/internal methods in the same assembly. It also started as something
small and simple that grew over time (evolution is never pretty).

Tell me about it :)
The assembly that is called by the custom action is actually the web service
assembly. All the types that the client application uses are defined in this
assembly (exported to the client side via a proxy dll), and the
installation/upgrade process directly accesses these classes as well as
calling database code. The custom action does a lot more then just database
upgrades, but that is one of the major chores.
Right.

I could move the functionality into a separate assembly but it would be a
PITA. On a new project I would start with that.
:)


My build program uses the DevStudio automation object to drive the build
process. What I like about that is that I do not have to worry about
dependencies, build order, etc. as the solution itself handles all that.
Anyone can change whatever they like in the solution (new projects,
refactoring, etc) and the build program does not need to change at all
(usually). I suppose I'll have to port over to MSBuild someday...

I'm sure there'll be an element of automation for that. I'm rather
looking forward to MSBuild myself.
 
Back
Top