Based on my requirements, should I use NSIS or jprofiler/install4j - nsis

We have a web application that we need to make easier to deploy for our clients.
The current workflow for a fresh install:
Ensure there is a JRE on machine (32 or 64bit)
Install Tomcat (32 or 64bit)
Create a database in Oracle or SQL Server (we provide SQL scripts for this)
Write some values into our settings table, like hostname. (Can get user to verify these, but dont want user to have to tap them in.
Create a connections properties file (we provide a mini JAR app to help with this) that will sit under Tomcat.
We have two WAR files for our actual web application. These can be split across two machines, but for now, lets assume they both get dumped under Tomcat.
Start Tomcat so that it deploys the WARs
This is a tedious process for our users
I want to encapsulate it into an installer and have been looking at doing this in NSIS which seems to have a large community, but then also stumbled across install4j, which although seems to be lesser known, is more specific to java based applications.
Just wanted to get some feedback from more experiennced users out there on the best choice for platform.
I do not want to get half way in, and then realise I have chosen the wrong installer platform.

Disclaimer: My company develops install4j.
First of all, install4j is a commercial tool, so that's a considerable difference to NSIS. Other major differences are:
install4j is a multi-platform installer builder for Windows, Mac OS X and all POSIX compatible Linux and Unix platforms.
install4j's main focus is for installing Java-based applications, for example it handles the creation of launchers and services and provides several strategies for bundling JREs. Many things that you need for a Java application will work out of the box.
install4j provides its own IDE which focuses on ease of use
Scripting is done in Java. The IDE provides a built-in editor with code-completion and error analysis. Actions, screens and form components have a wide range of "script properties" that allow you to customize the behavior of the installer.
For install4j, I can address your single requirements:
Ensure there is a JRE on machine (32 or 64bit)
In the media wizard, select a JRE bundle. If you select the "dynamic bundle" option, it will only be downloaded if no suitable JRE is found.
Install Tomcat (32 or 64bit)
I would recommend to simply add the root directory of an existing tomcat installation to your distribution tree.
As for the service, you can either use the Tomcat service launcher from the Tomcat distribution or create a service launcher in install4j. In both case you can use the "Install a service" action on order to install the service.
Generated services have the advantage that an update installer knows that they are running and automatically shuts them down before installing any new files.
Create a database in Oracle or SQL Server (we provide SQL scripts for this)
Use the "Run executable or batch file" action in order to run these scripts.
Write some values into our settings table, like hostname. (Can get user to verify these,
but dont want user to have to tap them in.
Any kind of user interaction is done with configurable forms. With a couple of text field form components you can query your settings.
This also works transparently in the console installer and the automatically generated response file will allow you to automate installations in unattended mode based on a single execution of the GUI installer.
Create a connections properties file (we provide a mini JAR app to help with this) that
will sit under Tomcat.
If you already have a JAR file which does that, just add it under Installer->Custom Code & Resources and add a "Run script" action to your installer to use the classes in your JAR file.
Any user input from form components that has been saved to installer variables can be accessed with calls like
context.getVariable("greetingOption")
in the script property of the "Run script" action (or any other script in install4j).
We have two WAR files for our actual web application. These can be split across two
machines, but for now, lets assume they both get dumped under Tomcat.
If you just add the Tomcat directory structure to your distribution tree, you can have these WAR file pre-deployed. Otherwise you can use "Copy file" actions to place the WAR files anywhere.
Start Tomcat so that it deploys the WARs
That's done with the "Start a service" action.

Related

Required production files for custom modules

I created some custom modules and Visual Studio drops the build files directly into the Kofax Bin directory. It is important to note that I'm using the modules as Winforms applications and Windows services (at the same time). The generated files are
MyModule.exe
MyModule.exe.config
MyModule.InstallLog
MyModule.InstallState
MyModule.pdb
I think that I only need the .exe file here. Of course I also add the .aex file to the directory to install the module. I also created two batch files to register the module on the local machine
RegAscEx.exe MyModule.aex
pause
and to install the module as a Windows service
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe" "%~dp0MyModule.exe"
pause
after running them as administrator I can delete them from the directory of course. I would like to know if it should be always fine to provide the .exe file, .aex file and the two batch files (which will be deleted later) only?
Basically correct. Some thoughts:
Build your application using the Release configuration (vs Debug). See discussion here.
PDB files usually are not needed in production. Still, you may want to generate and keep them if you plan on debugging in production.
The app.config file should be kept. Maybe you want to use application settings later on, and the supportedRuntime element is useful if someone wants to run your CM on a machine without that version of .NET framework being present (Windows will show a nice error message)
Keep the AEX file. This is required if someone wants to register your CM on another machine (e.g. deploying from DEV > TEST > PROD).
Include a single batch file that allows registering your CM on a new machine as well as adding it to Kofax Capture. Here's an example:
rem "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" SmartCAP.CM.Sample.dll /codebase /tlb:SmartCAP.CM.Sample.tlb
rem RegAscSc.exe /f Register.inf
Another thing I usually include is the ability to install my CM in a similar fashion to native KC modules, for example: SmartCAP.CM.Sample.exe -install and SmartCAP.CM.Sample.exe -uninstall. Take a look at the AssemblyInstaller class for details.

How to build MSI package on a linux server?

I have a windows desktop application which is currently available on a Linux server for download on user's machine. I want to automate the process of MSI packaging on the same Linux server using any EXE/DLL.
I have an App.exe and App.txt file. Some information should be read from text file and injected into exe before creating an MSI package. This entire process has to happen dynamically in the Linux server only after the user clicks on download.
Can anybody point me in the right direction as to how i can achieve my goal? I want to achieve the same by having minimum dependencies on any additional/3rd party tool. TIA for any time and effort.
p.s - I have done some R&D about various installers but none of them were matching the criteria as they have too many dependencies.
False Positive Risk: Creating a new binary for every user would seem to be very unwise because of malware scanners and their ability to recognize "known" versions of binaries (by hash).
If you create a new binary for each user, the malware suite might suddenly start to quarantine your setup without any warning or sense. This problem is not trivial anymore as malware control is hardened everywhere and setups that run with elevated rights are "prime suspects for risk management".
Digital signatures can help, but they are merely a guarantee that you made the setup, and not a guarantee that the setup doesn't contain anything harmful. Nothing worse than signed malware vectors. In fact it is proof positive that the malware came from you :-). Note: some people even manage to tamper with signed executables. The combination of the latter two fact is very troubling.
Application Setup: I like to eliminate such features and details from the setup and make the application itself responsible for it own configuration on first launch after installation. I find this more reliable and easier to debug.
Custom Configuration: You can apply custom configuration information at runtime via various mechanisms. You should add in a transform, or you can create a batch file next to the setup with this information embedded and pass to the MSI or the setup.exe.
Batch File?: The msiexec.exe command line supports passing parameters to the MSI. You can generate a batch file that will run the setup with such parameters if you design your setup to support these "incoming" parameters.
msiexec.exe /i myinstaller.msi ADDLOCAL="Program,Dictionaries" SERIALKEY="1234-1234" /qn
Transform: You can also create a transform to contain the parameters (a transform is a tiny MSI fragment with settings and changes to the original MSI):
msiexec.exe /i myinstaller.msi TRANSFORMS="mytransform.mst" /qn
A transform would be difficult to create on a Linux box, seeing as they are COM-structured storage files native to Windows only. I am not sure if it is even possible, but maybe.
Some Links:
Can the resulting command line be determined after running an .msi installer?
Change Program Name and Shortcut Title during installation
How to make better use of MSI files
We have had some success with wixl from msitools.
Also WiX will run under WINE.
However, in both cases we have not had EmbedCab="yes" work, which may or may not affect you.

Can i get source code of msi file in linux and add some conditions?

i have a .msi file . i want to add functionality in the installer.
i want to add
License Key Condition ,when someone try to install the application.
i don't want others to use this application. Only for those who have key for this software.Please help me if you can. Thanks
This question needs some improvement and clarification I think, but I will attempt an answer.
The application itself should be designed to allow license keys to only be accessible for certain users. Generally this involves storing the license in HKCU rather than HKLM. You cannot really change this in the setup, it is the application that will expect to read the license key from a predetermined source. Some applications are able to store license keys both per-user or per-machine - it all depends on its design. What application is this?
One way to "emulate" this for applications that only register the license key per-machine (for all users), is to remove the shortcuts to launch the application for users who do not have rights to use the application. This can involve installing the MSI "per-user", but it doesn't always work as intended.
It also depends on how you will distribute this software. Does it get installed remotely from a deployment system such as SCCM, or will you install interactively on every computer? If the latter is the case, you can install as the user who will use the application, and check if there is an option called "Install for current user" (or equivalent). If you deploy remotely you should create a transform to set the same option (install for current user) and invoke the install via SCCM whilst that user is logged in.
Where does Linux fit into this equation? Are you running Wine or some emulation software?

Setting Up Continuous Deployment of a WPF Desktop Application

For a project I am currently working on, I need to create a setup application for an existing desktop application. The setup application will be downloaded from a website, and will download required files to the correct locations. When the application is started, it will look for newer versions of these files, download them if any exist, then start the application.
I am using Visual Studio Online with TFVC, linked to Azure. I have a test application set up so that when I trigger a build, Release Management finds the build directory, and moves the files to Azure Blob Storage, but prepends a GUID to the file names being transferred. So what I have in my storage container is:
{Some GUID}/2390/Test.exe
{Some GUID}/2389/Test.exe
{Some GUID}/2387/Test.exe
...
What I want in my container is the latest version of Test.exe, so I can connect to the container, and determine whether I want to download or not.
I have put together a NullSoft installer that checks a website, and downloads files. I have also written a NullSoft "launcher" that will compare local file versions with versions on the website (using a version xml file on the website), and download if newer, then launch the application. What I need to figure out is how to get the newer files to the website after a build, with automation being one of the goals.
I am an intern, and new to deployment in general, and I don't even know if I'm going about this the right way.
Questions:
Does what I am doing make sense for what I am trying to accomplish?
We are trying to emulate ClickOnce functionality, but can't use ClickOnce due to the fact that the application dynamically loads a number of DLLs. Is there a way to configure ClickOnce to include non-referenced DLLs?
Is there a best practice for doing what I'm describing?
I appreciate any advice, links to references, or real-world examples.
You are mentioning ClickOnce, which you investigated but can't use. Have you already tried an alternative: Squirrel? With Squirrel you can specify which files should be part of the installation, allowing you to explicitly specify which files to include even if you load them dynamically.
Link: https://github.com/Squirrel/Squirrel.Windows
Squirrel is a full framework for creating an auto-update application and can work with Azure Blob Storage hosting (and also CDN if you need to scale up)

JavaFx 2 - Self Contained Applications and their preferences, database, etc

Let say i have a cross-platform runnable application
This application create then read/write some data and preference in external files
Bundle hierarchy is as follow:
ApplicationFolder/application.jar
ApplicationFolder/database.odb
ApplicationFolder/config.xml
Whether it's on a Mac, Windows or Linux, the application knows that everything is next to her (ie: /database.odb or /config.xml)
Now comes the Self Contained Application feature provided by JavaFx 2
The application is embedded in .exe on Windows, .app on Mac and don't know yet about Linux...
As a Mac user i've tested it on Mac and saw that database.odb and config.xml are now created at the user root path
I thus agree that i should think of a cross-platform mechanism to save/read my application preferences regarding the operating system
But i'm not quite sure of what to do and how to do it (can't find any googling help either..)
On windows, the .exe is installed in a folder, so i guess i can keep the same behavior
On Mac, the .app is a folder and i should keep everything inside (how to get the .app path ?!)
Isn't there a built-in mechanism in Java/JavaFx ?
Thanks a lot for any comment, advice, documentation or else that you could give me
Badisi
There are many ways to do this. I have listed some of them here in no particular order. The recommended approach depends on the type of data being stored.
Java provides a couple of mechanisms (e.g. the properties API and the preferences API) for maintaining application preferences.
If your application is sophisticated enough to benefit from an database, then you might want to use Java EE or Spring, both of which have their own configuration mechanisms.
For read-only configuration, you can bundle the relevant files inside your application jar.
To store customized application configuration files or client application wide databases in relative to the application jar, write the required files at runtime. See How do I get the directory that the currently executing jar file is in?.
For user specific configuration, use System.getProperty("user.home") to retrieve the user's home directory, then create a subdirectory for your preference storage (for example "{$user.dir}/.myapp") with hidden file attributes so that it doesn't show up on a standard file directory list.
If your app relies on internet connectivity, then you can store some of this information server side rather than the client and make use of it from the client using internet protocols. An advantage of this approach is that user configuration and data is automatically ported across client machines.

Resources