Merge msi and exe - c#

My deployment project creates and .msi-file and an .exe-file. Is it possible to merge these into one .exe?

Yes, you can create a self-extracting installer containing both MSI and the setup.exe bootstrapper file.
I think it is possible to do that with WinZip, or you can use IExpress coming with Windows. Here is a guide how to create a self-extracting executable with IExpress. You can either use the IExpress wizard or manually write a config file which you then can execute in the post-built step of your setup project, e.g. by calling
IExpress /N /Q MySetup.sed
A sample configuration file would look like this:
[Version]
Class=IEXPRESS
SEDVersion=3
[Options]
PackagePurpose=InstallApp
ShowInstallProgramWindow=1
HideExtractAnimation=1
UseLongFileName=1
InsideCompressed=0
CAB_FixedSize=0
CAB_ResvCodeSigning=0
RebootMode=N
InstallPrompt=%InstallPrompt%
DisplayLicense=%DisplayLicense%
FinishMessage=%FinishMessage%
TargetName=%TargetName%
FriendlyName=%FriendlyName%
AppLaunched=%AppLaunched%
PostInstallCmd=%PostInstallCmd%
AdminQuietInstCmd=%AdminQuietInstCmd%
UserQuietInstCmd=%UserQuietInstCmd%
SourceFiles=SourceFiles
[Strings]
InstallPrompt=
DisplayLicense=
FinishMessage=
TargetName=MySetup.exe
FriendlyName=My cool application
AppLaunched=CMD /C setup.exe
PostInstallCmd=
AdminQuietInstCmd=
UserQuietInstCmd=
FILE0="setup.exe"
FILE1="MySetup.msi"
[SourceFiles]
SourceFiles0=
[SourceFiles0]
%FILE0%=
%FILE1%=
There is a little caveat however with the self-extracting installer scenarios. Due to another fix these scenarios are broken with the bootstrapper (setup.exe) created by VS2008 SP1. For a workaround see the following thread: http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/3731985c-d9cc-4403-ab7d-992a0971f686/?ffpr=0.

I like it, you can see how to use IExpress on this link!
The only problem I see was that I've generated a installer on Windows Vista 64bits, I was trying to install the generated .exe in a server with Windows Server 2008 32bits, but it throws an error about processor type.

Another option could be 7zip with sfx plugin: http://www.7-zip.org/download.html or WinZip self extractor: http://www.winzip.com/prodpagese.htm

Related

How do I install NUnit 3 console on Windows and run tests?

I want to run tests from a console like this (being in any directory, the DLL file can be for a different .NET version):
$ nunit3-console test.dll
I googled a lot, but can't find how to set up this.
The official tutorial has nothing useful and is complete zero. Following it gets me nowhere: https://github.com/nunit/docs/wiki/Installation
It is hard to find, because there is a lot of outdated documentation, either for NUnit2 or NUnit3.
Steps:
Official NUnit3 console installers are here: https://github.com/nunit/nunit-console/releases (path is different than in docs)
Download NUnit.Console-*.msi package and install
Add to system PATH variable this: C:\Program Files (x86)\NUnit.org\nunit-console
Open command line
Type:
$ nunit3-console test.dll
// For running multiple test assemblies in parallel see: https://stackoverflow.com/a/45486444/1453525
I am using NUnit3-console.exe with Selenium WebDriver to run my automation, all of which is written in C#. I have multiple environments set up under discreet logins of Windows Server 2012.
NUnit-Console doesn't have to be "installed", although the .msi is readily available. Instead, I use the .zip and extract the files to a directory, C:\Nunit, rather than allowing the invocation to resolve from the PATH. All invocations are from a Windows Forms scheduler in the form -
C:\Nunit\NUnit3-Console.exe -work:C:\Users\xxxx\Automation\TestResults\ -out:TestResult.xml --where "name =~ 'yyyy'" --p environment=qa;browser=Firefox;browserSizeX=1200;browserSizeY=800 "C:\QA_Libraries3\zzzz.dll"
The test parameters are passed on the command line and the NUnit results plus results from the test are extracted from the TestResult.xml which is distinct for each user (environment).
What I do and recommend is to add nuget package NUnit.ConsoleRunner. Note that there are similarly named packages (NUnit.Runners, NUnit.Console) that might work too, but I know that NUnit.ConsoleRunner for sure has the nunit3-console.exe in it ... well at least the version of the package that I'm using (3.4.1) does :) Sadly, nunit versioning and packaging seems to be messy. There are lots of old docs and packages that seems to overlap. And I can't find good/solid up-to-date docs.
Anyway, once you get that package then you can run the exe that's now under your packages directory. For me it's packages\NUnit.ConsoleRunner.3.4.1\tools\nunit3-console.exe. This works well for calling from a build automation script that is in the solution folder or knows how to find the solution folder.
There's another option that although is not a direct answer to your question does get to what I assume is your desire: to run your nunit3 tests from the command line. If you add package NUnit3TestAdapter, then you can use Visual Studio's built in runner, vstest. If you open a Developer Command Prompt (or PowerShell), then it can be run as 'vstest.console' (without path info since the exe is in the path env var). Of course it has its own command syntax to learn.
I realize this thread is a bit dated, but here is how I run a specific SINGLE test.
install nunit-console (https://github.com/nunit/nunit-console/releases/latest)
Open a powershell window and run nunit3-console.exe with "--test" option set to reference the specific test you want to run (including namespace and class). and finally, provide the location of the assembly where the test can be found.
Example (paths need to be adjusted to point to your specific files):
& "C:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe" --test=MyApp.Mvc.WebTests.CardsControllerTests.TheNameOfYourTestMethod "c:\src\MyApp.Mvc.WebTests\bin\Debug\MyApp.Mvc.WebTests.dll"
Hope this helps someone.

How do I mimic the build and deploy functionality in the AWS Toolkit for Visual Studio via a script?

I have a .NET solution with several different projects. Each of them I have now set up via the AWS Toolkit so I can just right click and hit "Redeploy to AWS..." but what I would like to do create a script (PowerShell maybe?) that builds and deploys all of my projects automatically.
I know there is a CLI version of the AWS Toolkit called awsdeploy.exe but it doesn't seem like that will perform the compilation and archiving of a project like the AWS Toolkit plugin does.
How do I mimic this behavior?
So I'm currently tackling this question at work, with partial success. What I have found is that you can do the packaging with msbuild, and then deploy with awsdeploy.
For example, if I have a visual studio solution call bas, with two projects, foo and bar, and I want to deploy bar, then I first package bar with msbuild.
msbuild bar/bar.csproj /t:Package /p:PackageLocation=barPackage.zip
This should create a package call barPackage.zip under the bar directory. If you don't find it, look at the msbuild output as it should let you know where it was created.
Now that we have the package, we can deploy. Awsdeploy needs a configuration file. It's just a file that contains key value pairs of the form "key = value". There is an example file in a directory called Samples\, in the same directory where the awsdeploy.exe is located.
If you are using visual studio there is an option for creating the config file while deploying to aws.
More info: http://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv-deployment-tool.html#deployment-tool-configuration-file-format
Let's assume we have a configuration file called deployConfig.txt then we can call awsdeploy like so
awsdeploy /r deployConfig.txt
Note that the /r is for redeploy. This assumes that you already have an environment running.
If you don't want to put credential inside the file, you can also do.
awsdeploy /r /DAWSAccessKey=stuff /DAWSSecretKey=stuff deployCon
In general anything we don't want on the file we can specify on the command like by adding /Dsomething=stuff. As you can see above to specify AWSSecretKey we do /DAWSSecretKey=stuff.
The visual studio generated file does not list the location of the package so what I've been doing is
awsdeploy /r /DAWSAccessKey=stuff /DAWSSecretKey=stuff /DDeploymentPackage=bar/bar.zip deployConfig.txt
This almost works for me. But sadly it doesn't quite do the trick. It deploys the package, and I can see the environment trying to load it but fails at some point. I don't know why it's failing to load it. It loads it fine when I deploy it from visual studio.
This is how we're handling it. All of this runs on our CI server:
Step 1 - build web deploy package with msbuild:
msbuild website.csproj /t:WebPublish /p:WebPublishMethod=Package
/p:DesktopBuildPackageLocation=website.zip /p:Configuration=Release
/p:DeployIisAppPath="Default Web Site"
Step 2 - deploy with awsdeploy:
awsdeploy.exe /DAWSAccessKey=**** /DAWSSecretKey=**** /r config.txt
config.txt:
DeploymentPackage = .\website.zip
AWSProfileName = ******
Region = us-east-1
Template = ElasticBeanstalk
UploadBucket = ***********
Application.Name = ***********
Environment.Name = ***********

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.

Deploy C# ActiveX in a CAB for Internet Explorer use

I am desperately trying to deploy an ActiveX for IE developed in C# as a CAB archive. I have read many resources (some of them from StackOverflow) and it appears a lot of people are having the same problems. I have tried 3 solutions: a) creating a CAB VS project, b) manually creating a CAB using CABARC with a COM registration in INF and c) manually creating a CAB with launching msiexec. None of them worked. I even tried d) creating a bootstrapper which launches msiexec to no avail (because some people suggested simply launching msiexec on Vista can't work).
I am running Windows Vista but my project fails to run even on IE6 on XP.
When I install ActiveX using MSI, all is fine on ALL Windows. Apparently CAB thing is not working and I could not find a proper way to debug this whole process yet.
Any help is appreciated.
Update: Note that this old but excellent answer is still a very good outline for how to approach solving this problem, at least as along the evolutionary scale as Win7 and IE11. I just succeeded making it all work using the Answerer's Firebreath.org toolset as a jumping off point. It's not simple but it can be done. I've added a reference to that project to the reference list below since it may make a more logical jumping off point for current developers than this overview is.
Hooray - I have just finished an identical project, so you'll be pleased to know that it's actually possible. I have only tested this on XP - I understand there may be issues where Vista/7 don't allow msiexec to be called.
Given that you have an assembly correctly exposing a COM interface, I did the following:
Strong-named the assembly.
Created an INF file
Created an MSI using the Visual Studio 2008 "Setup Project" template.
Created a CAB file using "iexpress.exe" bundled with Windows XP.
Create INF file
The *.inf file I used looks like:
[version]
signature="$CHICAGO$"
AdvancedINF=2.0
[Setup Hooks]
install=install
[install]
run=msiexec.exe /package """%EXTRACT_DIR%\SampInst.msi""" /qn
The only bit you should need to change is the SampInst.msi. Note I would use an 8.3 filename, as long filenames can cause issues. While testing, I would not use the qn switch either, as that is a silent install.
Create the Installer
The installer has to do only one thing, and that is register the assembly by calling RegAsm on it. Most installers will provide some method to easily do this. For example, an installer created through VS 2008 will simply need to have the “Register” property of the assembly set to “vsdrpCOM”. Note that vsdrpCOM should be chosen as it generates the appropriate registry entries at build-time. The vsdrpCOMSelfRegistration setting is likely to fail as it calls RegAsm at run-time, and will thus not work for non-administrators.
Package the installer into a CAB file
This can be done by any cab archiver. Windows XP contains iexpress.exe, a wizard driven archiver, while Microsoft’s CAB SDK contains cabarc.exe. Other 3rd-party tools are also available.
Note that you will need to reserve space in the CAB file for code-signing if you are going to sign the CAB.
You will need to CAB the INF file, and the MSI file. You will not need to CAB the Setup.Exe file.
Handy hint: The VS2008 Setup Project project type allows you to set a post-build step in the properties, so you can build and CAB in a single step. My post-build step looks like:
cd "$(ProjectDir)"
"%WINDIR%\System32\Makecab.exe" /f "VboCslib.ddf"
The DDF file format is documented.
Sample HTML page
The object tag is used to point to the cab file containing the installer. A very simple HTML page which would deploy an ActiveXControl would be:
<html>
<head></head>
<body>
<!--
ID : The id of the ActiveX control to be used in JavaScript.
CLASSID : The GUID associated with the ActiveX control.
CODEBASE: The location containing the CAB installer for the ActiveX
control. This could be a URL, or a relative path.
-->
<OBJECT ID="MyActiveXControl"
CLASSID="CLSID:FC36FAE1-48E0-4f6b-B469-E1B5A8C6D1AC"
CODEBASE="cabfiles\SampleCabFile.CAB#version=1,0,0,0">
</OBJECT>
<script>
MyActiveXControl.SomeMethod();
</script>
</body>
</html>
Handy hints
Ensure your installer installs on a "per-user" basis, not a "per-machine" basis. This will make it more likely to install if the user does not have admin privileges.
Trouble-shooting
Internet Explorer 6 actually provides a really useful diagnostic aid. Clear your Temporary Internet Files, then navigate to the web-page. If the installation does not work, go to your temporary internet files and you will see a couple of files in there. One of these will be an error log starting ?CodeDownloadErrorLog. Drag it to your desktop and open it in notepad, and it will give details on what it was trying to do when it failed.
References
Microsoft KB247257 – Steps for signing a .cab file
MSDN – About INF File Architecture
SN.EXE - Code Strong Programs with Strong Names
Nikolkos Craft – How To: Deploy .NET ActiveX Control
CodeProject – Create ActiveX .NET Step by Step
CodeProject – Downloading C# ActiveX Components through CAB file
MSDN - ALLUSERS Property (Windows)
MSDN – Non-Admin ActiveX Controls
MSDN – Microsoft Cabinet Format
Update: Firebreath.org has a toolset for generating browser plugins for many platforms. The IE/ActiveX code to solve the problem posed here is just a subset. But as of 6 Nov 2014, I found it easier to start with Firebreath and its instructions than to try to build up my dev environment and roll all my own solutions from scratch.

making software setup package issue

I am making software setup package, and previously I am using Inno Setup, and it works very good.
The current issue I met with Inno setup is, it does not support all languages for the setup UI, for example Simplified Chinese.
The setup project of VSTS 2008 supports almost all languages, but it does not support invoke another installer from the current installer to let end user install dependent software packages.
My program to publish is for Windows platform (Vista and XP), written in C# + VSTS 2008 + .Net 2.0.
Any advice for my problem?
thanks in advance,
George
As one of the comments to your question suggests, you may want to simply integrate the required language into your Inno Setup. You do that by adding the Languages section:
[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
This allows the UI to be displayed both in Englisch and Dutch. Other translations can be added accordingly.
The fact that Windows Installer does not allow "nested installations" (running an MSI from an MSI) can be annoying. You might, however, consider packaging the MSI installers into an UI-less (= silent) Inno Setup and have Inno Setup run the MSIs one by one.
EDIT
This shows you how you may run the EXE files to install your dependencies. Please note that they might be installed after your software. If it is required that they are installed before your software, you may need to code a little Pascal Script - this is explained in the help files.
[Files]
DestDir: {tmp}; Source: .\Files\sample.exe; Flags: deleteafterinstall;
[Run]
Filename: {tmp}\sample.exe; StatusMsg: Installing prerequisite
This includes file .\Files\sample.exe into the setup, copies it to the TEMP folder upon installation and removes it after the setup is done. Then, after copying your files, it runs TEMP\sample.exe and waits for it to finish.
EDIT 2
Regarding the OP's comment on the order of the items in the [Run] section:
There are two possible cases:
You're using Inno Setup to perform the actual installation of your software (copying files, registry entries, etc.) and additionally need to run the installers for the prerequisites.
You've got a separate installer for your software as well, and just need Inno Setup to run the installers for the prerequisites AND your software.
For case 1:
You do not need to put the your EXE file into the [Run] section at all, except you'd like to allow the user to start your application after setup as seen in many setups using a checkbox ("Run XYZ now?"). In that case, use the following line for your EXE:
Filename: {app}\yourprogram.exe; StatusMsg: Run the application; Flags: postinstall skipifsilent unchecked; Description: Run the application now
For case 2:
I'd order the entries in the [Run] section according to their dependencies. That is: first entry is the one that some others depend upon, last entry is your application setup. But I'm not sure about the order in which the entries are handled.
This might be answered in the docs for the [Run] section. When in doubt, try asking Jordan Russel (Inno Setup's author) for advice - he's a nice guy and when I last mailed him he was pretty quick replying.

Categories

Resources