Adrigo Gallus

I created a Deployment project in VS 2005 that has a custom action. The custom action creates a windows form that has a couple of text boxes in it. The user fills some values (e.g., a database connection string, username) in these text boxes (which already have some default values), clicks OK, and the installation continues.

Now, I want to install this application from the command line (using msiexec) without any input from the user. Effectively, I want the installtion process to "click the OK button by itself" when my custom action pops up the form.

How can I achieve this without creating my installer again

Thanks,
Adrigo



Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

RSchoe_MS

Adrigo,

I believe there may be a couple of options for you.

First one that comes to mind is to call msiexec directly with your msi

(for example - msiexec /i myapp.msi)

When I get into the office in the AM monday, I will check this out a little more for the other option(s) and see what may work...

Robert Schoen (Microsoft Visual Basic QA)





Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

RSchoe_MS

Looks to me that your main option is to use msiexec with the "/q" option (msiexec.exe /i myapp.msi /q)

Please take a look at msdn topic "Walkthrough: Using a Custom Action to Display a Message at Installation". It should be located at - http://msdn2.microsoft.com/en-us/library/9cdb5eda.aspx but for some reason I am not able to open that page right now. If you can find that in your local help that should be fine too.

Anyway - the main take-away here is that if there some handling of the default values that needs to be done - then you can likely do it in the "Install" overrides method in the custom action's...installer class that you have...otherwise the "/q" switch should silent all the dialogs....automatically...

Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)
MyBase.Install(stateSaver)
Dim myInput As String = Me.Context.Parameters.Item("Message")
If myInput = "" Then
Me.Context.Parameters.Item("Message") = "CUSTOM"
myInput = Me.Context.Parameters.Item("Message")
End If
MsgBox(myInput)
End Sub

I will monitor this thread to see if you need additional assistance.

Hope this helps

Robert Schoen (Microsoft Visual Basic QA)





Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

Adrigo Gallus

Hi Robert,

Thanks for your reply. I did have not check this thread since I posted the question because I found a solution. But, I want to clarify a few things:

  1. My custom action was just an assembly I created, but it did not derive from the Installer class. And perhaps, thats why the form opened by my custom action shows up even with /q option of msiexec. Is this correct
  2. I altered by custom action to not display the form if a certain public property is set, i.e., "msiexec /q myapp.msi" will display my form, but "msiexec /q UNATTENDED=true" will not. I read the value of the UNATTENDED property to decided if my form ought to be displayed.
  3. Your reponse gave me an idea of some sorts for a more robust way of reading inputs during an unatteneded install. Perhaps, I can have property called UNATTENDED_PARAMS_FILE set from command line (msiexec /q UNATTENDED_PARAM_FILE=params.txt) , and open that file in my custom action to retrive any values that I otherwise might have gathered from user during a normal (attended) install.
I will look into creating custom actions by deriving from Installer class when I get a chance. Thanks, again.





Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

PhilDWilson

Generally speaking, the right way to do this is not with forms displayed in Installer class custom actions. Unfortunately Visual Studio's choices in setup project UIs are somewhat limited.

In every tool I've ever worked with that builds MSI files, you create the dialog so that it is shown in the standard Next->Next UI sequence. The values entered are properties that you use later in the installation. In a silent install where the UI is displayed, you either use sensible defaults (like an installation directory in Program Files\Your Company Name\Your Product name etc) or you let the user set them on the command line:

msiexec /i <your msi> /q MYPROPERTY=somevalue

and then use MYPROPERTY in the install.

I get the impression that this general scheme doesn't work for you because you don't like the additional dialogs you can add to the setup project's standard UI sequence.

I'll add that you don't *need* Installer classes - if you're into C++ you can just write a custom action as a C++ function exported from a Dll. They work fine, and have done so long before .NET introduced Installer classes.






Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

bpeikes

What is wrong with forms displayed in Installer class custom actions They seem to be just fine. My main question is if it is possible to access msi variables from dotnet installer classes. Why would I even contemplate writing an entire project in dotnet, but then have to write installer functions in C++. It's a maintenance nightmare.

Are the properties you are talking about available via the Context.Parameters collection





Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

PhilWilson

Forms in installer classes: Most installs have a UI sequence at the front. Installer class forms mean you have a UI up front, then you run the install and start changing the system and then when everything is installed you show your Installer class forms. They run too late to collect input for the actual install because everything's already installed, and if your user input there requires you to stop the install then you're not just exiting, you have to throw an installexception and have everything rollback and uninstall. Whether the system is clean after that depends on you properly undoing any custom action changes you made. You've also introduced two UI sequences, one at the front and some number of other forms at the end. Also if someone wants to do a silent install, the UI sequence is meant to be invisible, and they don't want your UI showing up during the install. I'd argue that all this means that after you've installed your app it's more robust to run a configuration program out of your app instead of Installer class custom actions. Note that a lot of setup people have found installer classes unreliable.

http://geekswithblogs.net/vagmi.mudumbai/archive/2005/03/28/27473.aspx

http://robmensching.com/blog/archive/2007/04/19/Managed-Code-CustomActions-no-support-on-the-way-and-heres.aspx

http://blogs.msdn.com/astebner/archive/2005/03/10/392280.aspx

Installer functions with C++: Actually it's the Installer classes that tend to be a maintenance nightmare. They are not supported by MSI, so what happens is that a hidden Visual Studio C++ Dll gets packaged in your setup. Your Installer class call calls into this C++ Dll passing a bunch of parameters, then this Dll code loads the runtime into the msiexec.exe process,, locates your assembly, loads it, locates installer classes by reflection, instantiates them, calls the appropriate methods then unwinds the whole thing. In contrast, calling a C++ Dll is simple - MSI just calls it. Which of these do you think turns out to be more of a maintenance nightmare

With Installer classes you pass data via CustomactionData, /arg=value strings, these turn into a dictionary inb Context.Parameters. This is one way mechanism, so in fact Installer classes offer no more functionality than passing data to a managed code executable if all you want to do is run some of your code after the install (which is effectively where install custom actions are called).






Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

bpeikes

The maintenance nightmare comes from having to hire a competent C++ programmer in addition to our C# programmers. In addition, it looks like some of the issues in the articles you list are not true, (AFAIK)

From Vagmi Mudumbai's article:

"InstallUtilLib.dll is not completely silent."

While it is true that if there is a failure it pops up a window, you can make sure that it doesn't by catching and handling all exceptions.

"The methods do not have access to the MSI thread. So we would not be able to use properties or write to the MSI log file."

Context.Parameters and Context.LogMessage work fine. Perhaps this was added in 2.0

The second article just states that there are problems if your installer classes were built with different versions of the framework. If you are packaging your software, and you don't have the ability to make sure that all of your installer classes have been compiled in 2.0, or whatever framework you are requiring to be on the computer then you have a problem with your build process.

The third article complains that it adds an additional dependency by requiring the .Net framework. As far as I know, no one would create an installer with .Net managed custom actions for a non .Net project, so the requirement that the .Net Framework is installed is not an issue.

In addition, by using managed code custom actions, you can leverage the code that is already in your project. If you have a custom action which updates a users configuration file, why would you want to write two different parsers, one for the runtime of your application, and another for your setup project.





Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

PhilWilson

Your comments assume that what's going on inside the Installer classes is somehow the same as ordinary NET programming. It's not, just like C++ programming for drivers is nothing like C++ in Win32 apps.

No you can't catch exceptions and stop InstallUtilLib, that's the point being made. InstallUtilLib catches them and handles then. You see messages like "Unknown error in CorBindToRuntimeHost...".

It's a fact that you cannot write to the MSI log file. That's nothing to do with Context.Parameters and everything to do with the fact that you write to the log file like this:

http://msdn2.microsoft.com/en-us/library/aa371614.aspx

but you're not on the MSI thread with access to the installation handle.

The way installer classes are called is nothing to do with build processes. The issue is that you're likely to find your Installer classes running with a framework higher then the one you built them for. For example, if you know your 2.0 Installer classes work when the 3.0 framework is installed, then fine. The situation is similar to writing a COM object with .NET that's called by a client program - you get the framework that the client is using (or the latest one on the system). Nobody cares if you say "but I want them to run in the 1.1 framework" because you don't get a vote.

You can leverage your code without Installer classes by using executables. To run your own managed code there are no advantages to using installer classes when compared with running an executable and passing the same data via the command line.






Re: ClickOnce and Setup & Deployment Projects Automating input to GUI screens in Custom Actions

bpeikes

Do you have any examples on how to use executables in a setup project with data on the command line Do setup projects have any way to manage the control flow of the installation