How to show log in custom installer in wix - c#

I am making a custom installer in wix. This will have multiple steps for completing the even. Everything is working fine. Now I want the show some message line.
Step 1 starting
step 1 Running...
Step 1 Completed
Step 2 Starting
Step 2 Aborted. File missing.
Step 3 Starting
Which control will be suitable? Edit control? Please help with code for custom action so that I can append message from C# code.

Unfortunately, the Windows Installer doesn't provide a built-in mechanism to show UI like that. To get that level of customization, you'll need to create an ExternalUIHandler. Essentially, you create an executable that registers to get messages from the Windows Installer then kicks off the install and draws UI the way you want. As you might guess, it takes quite a bit of work.
DTF in the WiX toolset provides a lot of wrappers for the MSI functions you'll need to call to get it all working. See the SetExternalUI method on the Installer class in the Microsoft.Deployment.WindowsInstaller namespace to get started.
Good luck! Lots of work ahead.

Related

Creating a WIX installer with conditional operations

I have a Windows Form Project and I need to create an installer for the same. I need to add prerequisites like .net 4.5 and vC++ redistributables.
The basic issue is that I need the installer to work offline as well as online, and in those scenarios I need it to move through different dialogs that accept different sets of input from the users. Further, for offline verification task, a certain code is generated after the users have initially entered some inputs.
I need to ask if Wix should be used for this or should I use something else, and if Wix will be useful for resolving my above-mentioned issues.
a) Can I have condition based movement between dialog boxes?
b) Can I write custom code between dialog boxes to perform a certain task, after the installation has been initiated?
P.S. - I haven't worked with Wix before, so links that might help me in building the installer will be of real help.
#Prashant,
1) Have you looked at Conditional Statements yet? Here's a pretty good example that covers a lot of what you're trying to do.
How to install features depending on the value of property
http://wixtoolset.org/documentation/manual/v3/xsd/wix/condition.html
2) Depending on what tasks you are trying to perform, there might be an existing Wix Component that covers it. If not, you can also execute Custom Modules as illustrated here.
http://wixtoolset.org/documentation/manual/v3/xsd/wix/customaction.html
http://wixtoolset.org/documentation/manual/v3/wixdev/extensions/authoring_custom_actions.html
https://blogs.msdn.microsoft.com/jschaffe/2012/10/23/creating-wix-custom-actions-in-c-and-passing-parameters/
How to add custom action to wix setup project
3) Are you aware of the following resources?
https://github.com/deepak-rathi/Wix-Setup-Samples
https://github.com/tom-englert/Wax
https://github.com/rstropek/Samples/tree/master/WiXSamples
There should be more than sufficient information here to get you going.

Asynchronous Drag and Drop to Windows Explorer

Question:
I need a DragAndDrop solution to download a file on drop in a folder of Windows Explorer for C# & .NET 4.0. It should not be necessary to have the file on the computer. The file will be big enough that the drag-time won't be enough to get the download done. I have found various questions, even accepted answers, but nothing that works. The very closest thing to something working is this demo project:
http://blogs.msdn.com/b/delay/archive/2009/11/16/creating-something-from-nothing-and-knowing-it-developer-friendly-virtual-file-implementation-for-net-refined.aspx
How to implement this code to download a file as part of the action of putting it to the drop place in Windows Explorer?
Web browsers solve this problem every day. Simplifying their model a little, do this:
Make a little program that performs your download given appropriate command line parameters. This little program should pop up a window with a progress bar and a cancel button.
Spawn this second program whenever the user "drops" something. This program will create the target file immediately and start filling it with data. It will maintain appropriate locks on the file until it is done downloading, at which point the "downloader" will exit.
If you're going to keep the "downloader" threads in the originating program, you will need some kind of download manager so that the user can get appropriate feedback on their downloads.
Okay, as Yahia said in the comments it's not possible without a proper shell extension for the different versions of Windows and .NET. You might have luck with the link I posted, but for me it crashes the Explorer and the developer thinks it works fine.
My honest opinion is with only .NET you can only do it with a FileSystemWatcher via copying special .temp-files, watching where they land, doing your task and replacing the .temp files when your task is done. Sad Windows.

c# main project and service

Despite my thorough googling, I am still confused on this matter.
Let me explain my situation. I created a c# project which gives the user the ability to back up the database manually (via a button click). Now the user must be able to schedule a time at which the database back up will run automatically. To achieve this, I am planning on creating a service which is started via the windows scheduler when the set back up time is reached.
I will need the deploy the service along with the main project (In my head, the service will be a different project. Maybe I am wrong here.).
My question is how do I deploy the service when the user installs the main project?
PS: I am using c# express and sql 2008 R2 express.
What are you using to install the main application. Chances are you the said packaging tool will also have hooks for allowing you to install the service. For example, if you are using Wix to create a msi package to install the main application, then you can configure Wix to also install the service.
This google search will point you to relevant articles for the same.
If instead you are not using any installer tool, say you simply give the user a zip containing all executables, then you will need to manually install the service. This article is perfect to create a self installable service. You could use Process.Start to execute the installutil exe to acutally install/uninstall the service.
Edit1:
Building on Rup's comment to your question, you already have the code required to backup the database. All you need, is to be able to schedule this. Once the user enters a schedule in your UI, you can create the corresponding task in the Task Scheduler. Have that task execute your main application, passing in the argument -backup "dbName" or what ever info is needed for the before mentioned backup code to run.
You may use the following template [which is meant for a console app, but will work just fine for your gui app as well. All you will need to check is if any switches have been passed in, then do not start the gui, instead simple execute the backup function code.] ... There are also a lot of existing questions on StackOverflow on which commandline parsing tool to use ...
The approach I would take is create the project for the UI, create a project for the service. The service would be a windows service that would always be running and would be responsible for creating the scheduled task. (Rather than having a scheduled task start the service.) How you go about creating the scheduled task is fairly open, you could shell out AT, or you could do some COM interop with the TaskScheduler type libs. I hope this helps.

Setup project with custom form

I’m currently working on a Visual Studio 2010 setup Project and would like to know if the following is possible:
1) Run the setup project in a way that the default forms don’t show, instead I’d show my own custom form that subscribes to setup project events. This way I'd show install messages and increase my own progress bar.
2) If 1 is possible, I would need a way to specify the default location.
3) I have a separate library project, where I have a custom install class (inherits from “System.Configuration.Install.Installer”) from within the install handler I’d like to be able to show custom windows forms, and control choices made by the user. I guess this is possible by adding a reference to system.windows.forms, but would this be the correct way to go about this? If I couldn't hide the default install form, these custom forms would appear over the default install one and I think it would look too great.
Suggestions, links etc appreciated
Thanks!
*UPDATE 1 *
Could I launch an .msi from c# code but also passing in a value.?
Just what this guy does here:
link
But passing in a value... then from my custom install class I take actions depending on this value.
UPDATE 2
Seems like I can:
link code project
UPDATE 3
I'm considering in doing the following, I'll start testing with a winforms app.
1) Launch winforms application.
2) Make a few webService calls, display data, user makes selection.
3) As per link in update 1, launch process(silent mode) and per update 2, pass in selected values.
4) Use some cross process events mechanism (WCF) so that my custom install class can notify my form of the different steps its running and update progress bar and messages.
You can create custom forms but the declaration needs to be done inside MSI. You can show a custom dialog via a custom action but that will not help you much since msi does this:
Load custom action dll
If it is managed the CLR is started and your maanged code executed
When the custom action is left the dll is unloaded and the clr is shut down
This is done every time a custom action is called. This is one of the main reasons why custom actions are normally written in C++.
To be more flexible you should use the WIX toolkit which allows .NET integration as good as it can be with MSI. MSI itself knows nothing about .NET and is a world of its own.
MSI itself defines dialogs and controls inside the msi via tables like the Dialog and Control table.
You could create a dialog and store your state in a msi property between each several msi actions which need to happen e.g. to calculate the disc space for the selected features and so on. But I doubt that this solution will be performant and I fear that starting and shutting down the CLR so often inside one process will expose you to CLR bugs that no one has encountered before.
To set the target location you only need to call the MSI method MsiSetTargetPath which you can PInvoke very easy.
To disable the normal UI you can override it completely or partially vis MsiSetExternalUI but I have not tried to disable only specific dialogs. If you want to hide specific dialogs you should check the msi tables of your current MSI to check if you can set a msi property to make the dialog think it has already been shown.
Yours,
Alois Kraus
As far as I know the setup projects made by Visual Studio are very limited unless you use custom actions. These Custom Actions can take a lot of time to create and debug so it might be wiser to use a more mature/featured tools such as Installshield
EDIT As for showing windows using winforms: that is ok but: a nice setup allows a silent/scripted install, make sure you allow this. Another thing to look out for is machines not having .NET and thus not being able to show the Forms... IMHO that is a no-no unless you are sure .NET (correct version) is present.
EDIT 2 In response to some comments: There are some scenarios that can't be implemented with VISUAL STUDIO Setup and Deployment projects. I am not saying that Windows Installer is bad. E.g., Try to make a custom installer to decide where an application will be installed and skipping the standard window that the project generates. I am not saying that custom actions are limited but they are IMHO not easy either.
Also, when you want use custom WinForms instead of Installer forms you have to make sure that the bootstrap of the .NET framework is done BEFORE showing any (WinForm) windows. It might be possible but if you want such customisation you might be better of with a more flexible tool.

Stopping installer inbetween

I want to stop my installer in progress programmatically through my installer class. I want to do this in before install event handler.However when I call Rollback(),I do not know the IDictionary SavedState to pass as parameter.I am passing it as null due to which the
rollback is throwing an exception.Does anyone know how to halt the installer from running
programmatically?.
If you are creating a setup project as part of Visual Studio you should be able to add a custom action into various parts of the installer. Within the custom action you can write code to achieve your result. MSDN Link

Categories