I'm trying to retrieve data from a Textbox in Visual Studio Project Installer but I simply keep failing. I have no idea how to retrieve data from, let's say the EDITA2 field and it seems the internet has no answers so far.
The project I'm talking about is a windows service you install with the mentioned installer. In the installer you can configure the service. I want to get data like server IPs and computer names and I want to use this data later in the running service. Talking of service, is there a possibility to automatically start the service after installation?
Summing up, i want to write data from the installer to a text file and to start a batch file after the installation process is completet. Can you help me please?
Thanks in advance for an answer.
I think you are searching for Custom Actions
https://msdn.microsoft.com/library/d9k65z2d(v=vs.100).aspx
https://msdn.microsoft.com/en-us/library/9cdb5eda(v=vs.100).aspx
To setup the StartType of a Service you require a ServiceInstaller
Maybe this helps
http://www.docstorus.com/viewer.aspx?code=7c7ccc28-6503-4779-877e-f350faab6741
This is the documentation for the Textboxes user interface dialog:
https://msdn.microsoft.com/en-us/library/e04k6f53(v=vs.100).aspx
The identifier EDITA1 (and others) is a property name that you can use later in (for example) custom actions. Without knowing exactly what kind of custom action you might be thinking of it's hard to say how you use it. In general, specifying it as a parameter to the custom action as [EDITA1] will cause it to be resolved to its actual value. But if you just want to store the values in the registry you'd create a registry item with the value [EDITA1].
To start the service in Visual Studio setups that install services with installer classes you'd need to overwrite the Install method, calling base.Install() and then adding code to start the service. Similarly at uninstall or upgrade time you can override the Uninstall method and stop the service before calling base.Uninstall().
These posts have some Textboxes examples:
Overriding "Textboxes" dialog fields from the command line in MSI installer (Visual Studio 2010 Web Setup)
Setup Project: user enters a value then store it in a text file or database
Visual Studio setups are not very useful with services and UI. There is no way to validate what the user enters at the time it is entered - if you validate it with a custom action it will be at the end of the install and the entire install will fail and roll back. Windows Installer has built-in support to start/stop/delete/install services but VS setups don't use it. If this is something you do regularly it might be useful to consider another tool, and that might have a learning curve but the resulting MSI will be more reliable and easier to use.
Related
I need to create a custom installer to deploy a specific program. But there are a few checks and balances that needs take place during intallation, and even though I have an Advanced Installer license, it just struggles to do everything I need.
I'm looking for a way to create my own msi file using c#. Running the msi file it will then start a win forms wizard, which in turn will do a number of items, including copying files to the host PC.
I'm not sure how I can "include" my set of files into a single msi file. How to you "copy" files into an msi and how can you read again from it?
I can't even give a proper sample code of what I've tried as I don't know where to start.
This just feels like it should be a duplicate question, but I can't find it.
I work at Advanced Installer, since you said you already have a license let's help you get a return of investment on that ;)
First of all, I seriously doubt you need to reinvent the wheel and write your own code that installs/copies files on the machine. This is a basic action performed by all installer authoring tools, and even though it seems simple when you first think about it, it is not. You don't want to write code that handles rollbacks (if your install fails), reference counts (if a file is shared somehow), repair/self-healing operations (if somehow a DLL gets corrupted or missing post-install), or cover other standard Windows Installer scenarios.
Since you didn't explain with full details what you are trying to do I will give you some short example on how to do each of the steps you mentioned:
Adding files in a setup package - this is a link to a tutorial created with a free edition, but the same steps apply for Professional and Enterprise editions.
Searching files on a disk and retrieving values from them. - for this, you need to use the built-in support from Search page. There you can either simply search for a file and return its path or search for an element inside an INI or XML file and return its value inside a property.
Windows Installer properties are the equivalent of variables in your code. You can use them all over the installer project to pass/get/validate values.
Designing custom dialogs. Most professional installer authoring tools have support to build custom dialogs. The previous link is for a tutorial on how you can do that with Advanced Installer.
During the UI stages, you can include and custom C# code to perform additional validations or data retrieval operations and pass that to or from the installer using properties. if you need it.
The custom installer dialogs support is available starting with the Enterprise edition. The Professional and Free editions include the standard dialogs, but with no options to customize them.
Another way to interact with users is to design an UI experience inside your application that is visible only when the users launch the application for the first time. So, this is not a part of your installer. It will be code that you write inside your application and you can provide a first-launch experience similar to what you see when you install Office for example. If you can give me more details on what you want to do/capture in those custom dialogs, I will try to recommend you the best approach.
After a lot of research I have to ask you guys in order to get my project finally running.
I want to save data which the user puts into a TextBox of the Visual Studio Project Installer to a text file. I have read different articles, also this one:
C# Visual Studio Project Installer retrieve data from Textbox
But the question was not answered there so I'm asking you to get this question finally solved.
And please give me a Code example where it is written in C# Code how to get this values from the textboxes and write it into a Textfile.
Is there a libaray of the installer tool?
Please help me I'm despairing more and more with this installer.
Thanks in advance for your help!
Edit1: You need to specify what you mean by "C# code". If you mean a custom action written in C# then say whether you mean an C# custom action or executable:
-> I have a big program written in c# code where I need the data from the textboxes. I thougt if it would be possible to write and therefore save the data of the TextBox into a .txt file. Then I could read it later in my big programm. Hope this answers your question.
Although a custom action would do this, the simplest way to do this is as follows, and it does not require creating a text file.
Create a registry key and item using the registry view of the setup project. View-Editor-Registry. You could use the exusting HKCU Software Manufacture etc key and add some extra folders.
Create an registry item by righ-clicking the key and add a new string value. You could call it MyEditString, and give it the value [EDITA1] assuming EDITA1 is the name of the textbox property. The square brackets cause it to be resolved to the actual value at install time.
When that program requires the value it just reads that registry item.
Otherwise, to write a C# custom action there is a walkthrough here:
https://msdn.microsoft.com/en-us/library/9cdb5eda(v=vs.100).aspx
where it shows a installer class example, and the key part is the "To add a custom action" section where it describes how to pass the text in the form /mystuff=[EDITA1] and the installer class code you'd say string myInput = Context.Parameters["mystuff"]; to get the value.
The problem with this approach is that creating a text file from a custom action is non-trivial. You need to specify the full path, and be aware that in a Everyone install your code is running with the system account.
In general this type of configuration step is best done the first time your app is used. It sounds as if this file is going to be changed by the user anyway if it's user-configurable, so make it part of the application.
If this is the installer that you are developing then Write a C# custom action and schedule it in install UI sequence. Use the property of the textbox to obtain its value.
But this can happen only on a button click or similar action by user.If you are looking for dynamic update then I am afraid that you will need to write custom bootstrapper UI as windows installer default UI doesn't support this.
Scheduling custom action in UI sequence
Authoring custom actions
I've written a WPF application with an accompanying Windows setup project. The application has an option to 'Run on startup', at which point a key is added to the SOFTWARE\Microsoft\Windows\CurrentVersion\Run registry. The setup project doesn't create this key by default because the option is disabled by default; however, I want to make sure if someone uninstalls the application the registry key will be removed.
Is this possible? Also, what is the behavior if the key isn't removed? I've assumed Windows will try to run the application and nothing will happen but I have yet to test this situation.
Edit - As requested, the registry key is set up from code as follows:
using (var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
if (key != null)
{
key.SetValue("MyApp", "\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\"");
}
}
It is done this way because by default, I don't want the app to run on startup; thus, the registry key shouldn't be created until the user opts to use that setting.
If you created that key data with an install custom action, then you'll need to create an uninstall custom action to remove it. Strictly speaking you should also include a rollback custom action to remove it in case your install fails and rolls back.
An MSI file is a database of changes to the system - that's why anything in there can be uninstalled, but it doesn't keep track of changes you make with your code.
I'd be tempted to make this an option somewhere in the application cofiguration, not the install, so the app could have an option "start at logon time" that the user could turn on and off. Currently anyone that wants to change that setting has to fiddle with the registry or re-install the app, depending on how smart they might be about this stuff.
With other install tools you get more choices. For example, Visual Studio doesn't do multiple features. With another tool (such as WiX) you could create a feature that the user checks if the Start is required, and that feature contains the component that creates the registry key using Windows Installer registry entries instead of code. Apart from there being no coding, the entry gets removed at uninstall time; the user can go into maintenance mode and uninstall (or add) the feature at any time; install failure will clean it up automatically. And that's just one way of providing the functionality.
Visual Studio setups are relatively easy to use because they expose only a limited set of Windows Installer features, so you get some simplicity but you pay for it if you want to go beyond the capabilities that VS setups provide. But you also get involved more deeply in Windows Installer.
I'm working on an installation and configuration application in C# for a project I'm working on, and I'm wondering what the best method of internally organising everything is.
Requirements:
Single executable for deployment, no other files bundled with it.
Has to support custom config steps on each panel, which contribute to a generated XML config file at the end.
Certain steps may be skipped based on certain choices made within the installer flow.
Must support dynamic config screens based on information fed back from classes in one of my libraries.
Here's a description of my prototype:
A large form with a bunch of Panel controls, each representing one "screen" of the wizard. Each is named appropriately.
A class for each "screen", deriving from a base type I defined. I call specific methods of it (e.g. Enter, Back, Forward) when certain events occur.
State is stored as a Dictionary<string,object>, which is passed to each screen. The final screen (the actual "Installing..." screen) reads config out of this and dumps it into the XML file.
Each screen's code is responsible for handling the "Next" and "Prev" buttons, so I can control where it jumps to based on settings in the current screen.
A number of modules are stored in my library which provide information about extra config steps that need to be taken. I'm implementing this through reflection and automated UI generation.
Assets are stored in the resources of the executable.
I don't want to use a generic installer package (e.g. InstallShield) because the logic is totally custom and calls upon one of my class libraries. What I would like to know is - am I setting this out in a really circuitous way? Is there a simpler or more standard way to wizard-style applications?
Here's the short answer:
A commercial tool is perfect for what you need because it supports both custom installation UI and dynamic XML files. Anything else requires a lot of learning and hard work.
And the long explanation:
A custom installation UI is not an easy task. Windows Installer offers built-in dialogs and controls, so it's usually the best solution. You could also try a proprietary installation engine, but you will need to learn it.
You're also taking an incorrect approach by trying to control everything with custom code and classes. Most setup authoring tools offer direct support for handling the installation UI and XML files. Why try reinventing the wheel?
So you basically need to find the setup authoring tool which is best for you. Here is a general list:
http://en.wikipedia.org/wiki/List_of_installation_software
The tools are either MSI-based or proprietary. Personally I prefer Windows Installer (MSI packages).
Trying to implement all your tasks with custom code is just not worth it.
The only proper way to install software on Windows (which I assume is your target platform) is using Windows Installer. Simplifying a bit Windows Installer is based on the concept of a installation package (a database file) that in a transactional way can be added or removed from the system.
If you write your own installation logic you will not be able to participate in the transactional handling of software installation. If your uninstaller gets deleted there is no way the user can uninstall your software. Also, Windows Installer knows A LOT about the quirks of Windows which you may not be aware of.
Windows Installer provides a somewhat cryptic API for creating packages but you can also use then open source WiX toolset which is quite powerful or any commercial installer like InstallShield.
If you decide to go the Windows Installer way you should try to avoid custom actions if possible. Custom actions suffer from the same "transaction rollback" problem as a custom installer. You create the code for the custom action rollback/uninstall say in a DLL and if that DLL is lost there is no way Windows Installer can undo your custom action.
Windows Installer is actually quite powerful. You havn't given any specific information about the "custom stuff" you need to do but perhaps Windows Installer already has a table for that?
Use InstallShield or the MSI installer. Seriously. In addition to being able to support all kinds of custom logic (including code you specify), the generic installer wizards do things you're not even thinking about, like, say, listing the installed app in Programs and Features, and performing repair installs/uninstalls.
With the level of custom logic you're looking at, I would fork out for the latest InstallShield installer builder; the VS Install project builds into a pretty simple dialog set.
EDIT: Fair enough, been in that position before.
I would still HIGHLY recommend using any generic installer tools you have available, like VS's Install project, for the reasons I stated above; the install packages do things you aren't even thinking about in your design, and you get all of it for free.
Instead of putting this logic to customize your XML config file in the installer, how about putting it in your executable, as a "run-once" configuration wizard that the user will see when they start the application after installing it? It shouldn't be too off-putting to your users, and it should work well if the actual application is also a WinForms app (even if it isn't; you could compile the configurator into a different app and have your main app launch the configurator if it doesn't have an XML file).
Single executable for deployment, no other files bundled with it.
This might of some interest to you : http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
How can we prompt for a computer restart after install from within a C# custom action?
We are using VS 2005's setup project for our setup, and we need to programmatically decide to prompt for a restart (so it will not happen on every install, just on some).
UPDATE: We're looking for something that is already built into the MSI custom action system first. If that doesn't exist, we can resort to restarting the PC ourselves somehow, but would like to avoid that.
UPDATE: We see where you can set REBOOT=Force when edited the Msi in Orca, can you modify these tables from a C# custom action at runtime? We could set this to restart every time, but that might make our setup annoying (it will only need to restart on rare occasions).
UPDATE: We tried setting:
savedState["REBOOT"] = "Force";
From within the Install() method of our custom action, but no luck. It doesn't seem like the IDictionary, savedState really does anything.
Also tried:
Context.Parameters["REBOOT"] = "Force";
But I think this collection is just the command line arguments passed to the custom action.
UPDATE: Is there a way to edit our MSI with Orca to make this trick work? Maybe schedule a reboot on a condition of some file existing? We have not found how to set MSI properties from a C# custom action.
UPDATE: We tried hooking into AppDomain.ProcessExit and AppDomain.DomainUnload and starting a new thread and calling Process.GetCurrentProcess().WaitForExit() and none of those events will fire from within a C# custom action...
You need to add or call the MSI custom action ScheduleReboot http://msdn.microsoft.com/en-us/library/aa371527(VS.85).aspx in your InstallExecuteSequence, . You can do this by using the MSI function MsiDoAction, http://msdn.microsoft.com/en-us/library/aa370090(VS.85).aspx inside a custom action. Please note that the custom action that schedules this must be an immediate custom action, not a deferred custom action. This means you will probably need to schedule it after InstallFinalize. You could also add it to the InstallExecuteSequence with a condition on a public property that your custom action sets.
When I've had to do this before we used a Win32 API function from user32.dll, I think this was it: ExitWindowsEx()
LanceSc has given you the answer. You need to run ScheduleReboot, and the best way to do so is to insert it in the InstallExecuteSequence conditioned by your own custom property that you set inside your custom action.
As you mention, Wix is the way to go for future flexibility. Wix now also includes DTF (Deployment Tools Foundation) which is a rich set of .NET class libraries that wrap the entire Windows API. You can use this to easily access MSI databases from C# or to write C# custom actions. I can provide more info on this if desirable.
As it seems, the only way for us to solve this is to either:
A) Modify the MSI with orca to make the setup restart for every install
B) Redo the setup project with WiX or Install Shield
Thanks for the help guys.