MSIEmbeddedChainer & MSIEmbeddedUI - c#

i am finding some example source codes for the MSIEmbeddedChainer & MSIEmbeddedUI. wix v3.0 has <EmbeddedChainer> command, but there's no info of how to use (or probably incomplete implementation). i want to chain my msis. however, there are very little details to this topic. msi 4.5 has very nice features with MSIEmbeddedChainer & MSIEmbeddedUI. unfortunately, wix v3.0 doesn't seem to support at the moment. i see the wix announced that wix burn project started along with wix v3.6. but i think there are long way to go for this implementation.
there are some developers wrote their own codes for this MSI chains with wpf and c#/c++. i just want to have a sneak, so i have an idea how to code them too. again unfortunately, i don't see any...
can anyone help please?

Burn.exe in Wix 3.6 onwards provides this feature by using Chain element and MsiPackage. Have a look at this.

an MSI chainer is nothing more than a program that you write yourself that calls your MSI's in the proper order with the proper attributes and properties. The MSIEmbeddedChainer element is actually included in WiX 3.0 (I am actually using it in my current istallation. Sadly I am not the one writing the chainer, I am only doing the MSI's. Try checking the WiX page for the element EmbeddedChainer (without the MSI) and you should see all the available elements.

Related

Add pages to installer -Wix Toolset

I'm looking for a way to add new pages to installer with its own interface. Ultimately, I would like my installer to do many things in turn, enabling the user to go to the next pages and check or set subsequent configurations.
But at the moment I'm looking for how to add an additional page that would run before installation and check if the computer has the required programs to install the application. I would like to attach my ready code to c # to check if these programs are installed on the given computer.
By using this tutorial:
https://www.youtube.com/watch?v=6Yf-eDsRrnM&t=7195s
I created the basic version of the installer. In the tutorial we create installer by using WixUI_Minimal.
I have looked through the documentation and it is written that you can create your own pages, but I can't find anywhere. For example there
https://wixtoolset.org/documentation/manual/v3/wixui/
is Customizing Built-in WixUI Dialog Sets but they dont show how do that.
Update 21th April 2020
I have created a public GitHub Gist, which explains the steps and even include a customized Dialog PrerequisitesDlg.wxs with up to 5 Prerequisites, which can be configured as WiX Properties (text and condition). The whole sequence is wrapped in WixUI_KargWareFeatureTree.wxs.
Text before 20th April 2020
The element you need is UIRef Element, Wix Toolset v3 Documentation.
Wix Toolset is an open source project, so you can review it on GitHub, Wix Toolset v3.
The dialoges which are embed in Wix Toolset are listed here, Source Code of the Default UI-Dialoges of Wix ToolSet. I would use the WixUI_Advanced one, but you can pick all others or start even from scratch.
Download the WixUI_Advanced.wxs from GitHub
Copy the wxs file to the root of your msi-project (where the *.wixproj os placed) and name it to e.g. MyWixToolsetPages.wxs
Edit the name of the UI xml element inside MyWixToolsetPages.wxs (near to line 50)
Add the MyWixToolsetPages.wxs to your wixproject
Replace or add the UIRef reference element in the product.wxs to <UIRef Id="WixUI_MyWixToolsetPages"/>
Add your new dialog as <DialogRef Id="myNewPage" />
Customize the order of the pages with Control Next / Back and Event NewDialog
Be aware to test your sequence in both directions (next, next, next, end) and (end, back, back, back)
Change <UI Id="WixUI_Advanced"> to <UI Id="WixUI_MyWixToolsetPages"> inside your MyWixToolsetPages.wxs (copied from the original WixUI_Advanced.wxs)
...
<UI Id="WixUI_MyWixToolsetPages">
...
Replace the UIRef inside the product.wxs
...
<UIRef Id="WixUI_MyWixToolsetPages"/>
...
I maintain an open source wix authoring tool that enables you to do this by uncommenting one line of XML. The trick is to insert additional rows into the ControlEvent table causing existing paths to be overridden.
https://github.com/iswix-llc/iswix/blob/master/Application/IsWiXNewAddIn/MSISolutionTemplate/SetupProjectTemplate/UI.wxs
https://github.com/iswix-llc/iswix/blob/master/Application/IsWiXNewAddIn/MSISolutionTemplate/SetupProjectTemplate/UI-CustomDialog.wxs
Overall Advice: It is generally an anti-pattern - as of this IT-epoch - to do too much with your setup GUI. In particular it is
better to do per-user configuration as part of the application launch.
Rule of Thumb: You should limit setup-GUI to genuinely shared settings that need to be written with admin or elevated rights to
per-machine locations (inaccessible for normal users). Set everything else from application launch. This can also help QA personnel with their testing.
Burn: Burn is the WiX toolkit's setup.exe creator. It is a bootstrapper, chainer, downloader, installer, etc... construct. Hello-Burn sampler here. And about replacing Burn's default GUI.
WiX MSI GUI: I have a minimalistic sample here for how to change your MSI installer GUI: https://github.com/glytzhkof/WiXCustomDialog. This is the GUI embedded inside your actual MSI. There are other possibilities with GUI.
GUI: You can replace the GUI inside each MSI with a GUI from a Burn setup.exe. There are some details here. This GUI you can implement as a normal executable with all the bells and whistles that allows. The MSI GUI is rudimentary and old. There is another answer here on how to change installer GUI.

referencing and importing third party python libraries

I am fairly new to python, and come from a C# background. In C# l, third party libraries are commonly stored inside the project folder.
This means that libraries are totally internal to the project. The project then is not dependent on anything outside of the project folder (other than .net framework of course).
I really like this structure and have tried successfully to mirror this in python by copying the libraries into a lib directory, in the project root, and adding the lib folder to the python path on startup of the application.
I am worried that there may be something I am overlooking by doing this as I have looked around a bit amd have not really seen anyone else in thw python community doing this.
My question is simply - is this ok? Is there something that I may miss by simply dumping the necessary .py libraries in, rather than using easy install, and thus storing the libraries in site packages, at a system level?
Please feel free to let me know of any drawbacks you can see, no matter how simple.
Thanks!
I'll espouse the usage of virtualenv and pip for development purposes. This will give you exactly the sandbox that you are used to. As for distribution, use setup.py and reuse the requirements.txt file that you would use with pip install -r to install dependencies to generate the install_requires argument to setuptools.setup. I've been meaning to set up an example that shows this off a little - check out https://github.com/dave-shawley/setup-example for a nice example with some description too. I plan on adding a little more to this as time allows.
If you want to closely manage the dependencies of your code on the per project basis you might want to take a look at virtualenv.
Virtualenv will allow you to keep your dependencies close to your source but will remove the error prone manual copying of the .py files.
On top of that remamber that some packages are not pure python and they sometimes contain compiled C code - if you use virtualenv you do not have to worry about it.

Programmatically installing MSI packages

I would like to install a given .msi package programmatically from my C# .NET application, preferably with the installation parameters that my application specifies (like the installation path, decline crapware, etc.).
I did some searches, but I haven't really found anything useful. The most promising hit was this topic, but I cannot find any documentation of Microsoft.Deployment.WindowsInstaller or of WindowsInstaller.Installer for that matter.
I find the Deployment Tools Foundation project mentioned above to be a solid way to do this from .NET. Having referenced Microsoft.Deployment.WindowsInstaller.dll, use code like this to install a package:
Installer.SetInternalUI(InstallUIOptions.Silent);
Installer.InstallProduct(msiFilename, "ACTION=INSTALL ALLUSERS=2 MSIINSTALLPERUSER=");
The documentation for the .NET wrapper is in a .chm file in the Windows Installer XML installation directory in Program Files. Some parts of that DLL loosely wrap the native Windows APIs so the documentation here can be useful as well, which is how I worked out the string in the above snippet to suit my situation.
There's a COM object that offers an API for the installer:
First add a reference to COM object "Microsoft Windows Installer Object Library" to your project. Then you can start with the following code:
using System;
using WindowsInstaller;
namespace TestApp
{
public class InstallerTest
{
public static void Install()
{
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer installer = (Installer)Activator.CreateInstance(type);
installer.InstallProduct("YourPackage.msi");
}
}
}
And there's a documentation about the Installer Object.
The "Deployment Tools Foundation" project which is a part of the WIX3.5 install contains a .NET wrapper for most (if not all) of the Windows Installer API. Get it by downloading and installing the WiX install: http://wixtoolset.org/ (currently WiX 3.11, updated Aug.2017).
Locate the Microsoft.Deployment.WindowsInstaller.dll file in the %ProgramFiles%\Windows Installer XML v3.??\SDK\ folder. Set a reference in your C# project and try to run the different APIs and see if you get the desired functionality.
I highly recommend using Deployment Tools Foundation over any COM Interop from .NET code.
The basic Win32 API (that can be pinvoked if necessary) is MsiInstallProduct. This is where practically all other mentioned APIs and calls will end up.
https://msdn.microsoft.com/en-us/library/aa370315(v=vs.85).aspx
Just pass the full path to the MSI file and your command line (including quiet options etc) and check the result to see if it installed correctly.
Note that there is a simple p/invoke declaration for managed code:
[DllImport("msi.dll", CharSet = CharSet.Auto, SetLastError=true)]
static extern UInt32 MsiInstallProduct(string packagePath, string commandLine);
The very simplest solution is to use msiexec to invoke the installer on the .msi.
You can customise the installation using command line settings including setting .msi properties, silent installation etc.
There are two approaches to solving your problem.
The first one as mentioned by #Glytzhkof is to use the Microsoft.Deployment.WindowsInstaller .NET wrapper API. This is some seriously powerful stuff but requires some time to get familiar with. You can get the latest version here (UPDATE: Stein Åsmul 28.12.2018: DTF is now part of the WiX toolkit).
The other approach is to use Transforms (.MST files). Transform files can be generated using Microsoft Orca or InstallShiled. The MSTs contains all the customizations that you need and can be applied on the MSI using this command line:
msiexec /i somemsi.msi TRANSFORMS=somemst.mst /qb
Additionally you can pass parameters directly in the command line:
msiexec /i <somemsi.msi> /qb AGREETOLICENSE=YES INSTALLDIR=C:\Temp
etc...
However, you will need to edit the MSI in an ORCA/InstallShield to determine which parameters are actually used.
The parameters used in the above example are not universal.
The actual installation can be complicated because of the presence of custom actions etc. In fact there is a whole industry that is built around msi customizations. Its called Applications Repackaging.

Adding folder navigation to an msi

I am creating an MSI package for a windows service, untill recently i have always just performed the minimum using the installer class and then manually edited the app.config file afterwards. However, i need to make it easier for the users to carry out an installation themselves and this has meant replacing manual configuration with prompts at install.
I have managed to add a custom action to display a textbox and prompt for a folder destination, as well as ammending the installer to create the folder using the filepath entered into the text box, but i would prefer it if the filepath could be selected by browsing to the folder.
Can anyone suggest a good tutorial or steps to do this, as i am struggling.
Thank you
This would mean a redo, but you could use WiX to build your installer.
It has built in support for everything you need, and I don't think you would need any custom actions at all (unless there is something special you don't mention).
It does have a bit of a learning curve, however. Even if you don't go with it this time, it would be worth looking into for a new project.

How to increment a version number programmatically?

How do I programmatically increment a given version's number to the next version of the highest one?
For example if I have a file Program.exe with the following version numbers :
Program.exe 1.0.0.0
Program.exe 1.0.0.4
Program.exe 1.1.0.76
Program.exe 1.0.0.66
The next version number in this case would be 1.1.0.77
What's the easiest way to implement that?
Thanks for any help in advance
Use a version control solution, like Subversion or git, and/or a build tool.
Certainly a version control solution will provide functionality to insert version information into the source code as it is committed via a magic string you include in your source like $Rev$, which you can then use as a build number.
Here's a blog post showing how it's done with Subversion.
If you're trying to do that to set the program properties (not just in the source code as Brabster suggested), you could set visual studio to automatically change the build number. The problem is that the number is not sequential. Check out this link to see how easy it can be done.
Also check this post.
If you want an auto incrementing number that updates each time a compilation is done, you can use VersionUpdater from a pre-build event. This has the advantage of more control than the default numbering mechanism described on MSDN.
Your pre-build event can check the build configuration if you prefer so that the version number will only increment for a Release build (for example).
I always use AssemblyInfo Task (http://code.msdn.microsoft.com/AssemblyInfoTaskvers). Though it does not support the feature you want, it is an easy way to manage version numbers.
Check out this article on Codeproject that covers a Visual Studio addin to manage the version number of a project.
Hope this helps.

Categories

Resources