Can I run a command before the setup.msi? - visual-studio

I have a desktop application and its installer project produces two files in the Release folder: let's call them setup.exe and setup.msi.
In the post build event I sign the setup.msi with a self signed certificate. Then my final installation batch is composed of three steps
Adding user store certificate with a start.cmd (or start.exe)
Running the setup.exe. Notice that the important thing is that it shows a user account control for a verified author with my name and surname.
Removing (with a stop.cmd or stop.exe) the certificate at point 1 for security reasons/best practices since it is self signed
Now I'm perfectly fine with this solution, I only wished to include the commands 1 and 3 inside the setup.exe if it was possible in a standard way.
What I have tried to do is to define the start.exe and stop.exe as custom actions. In that case I only have the two files setup.exe and setup.msi but unfortunately I get an unkown publisher. I guess it is obviously because the custom actions go inside the .msi and not in the setup.exe. But I'm not an expert of installer projects so someone might suggest a better and standard solution.
Alternative approach
Is that something that I could much more easily do by switching to Inno Setup and maybe as suggested in this comment?
References
How do I create a self-signed certificate for code signing on
Windows? - Original Answer
Answer about certmgr.msc - Will a self signed code-signing
certificate get rid of “Unknown Publisher” warnings?
Sign tools downloadable from github

Updated answer
Sorry, I've tested my original answer below and it is "wrong" in a sense:
actually I get a single click installer but then the Windows operating system anticipates the user account control before such single click installer and it shows an unknown publisher, which defeats the purpose of point 1 (and 3).
So, short, updated answer: it is impossible(*) to do that in a standard single-click exe, like the ones produced by the SFX module mention below.
(Note *): though it is doable by compiling a custom C# code and by adding files to the Resources.resx, for example _7zr.exe, etc... like in this example:
using System.IO;
using System.Diagnostics;
namespace selfextractinstaller
{
class Program
{
static void Main(string[] args)
{
string file_path_7zr = #"_7zr.exe";
using (FileStream fs = new FileStream(file_path_7zr, FileMode.Create))
{
byte[] pgm_bytes = Properties.Resources._7zr;
fs.Write(pgm_bytes, 0, (int)pgm_bytes.Length);
}
string file_path_config = #"config.txt";
using (StreamWriter sw = new StreamWriter(file_path_config, false))
{
sw.Write(Properties.Resources.config);
}
string file_path_7zSD = #"_7zSD.sfx";
using (FileStream fs = new FileStream(file_path_7zSD, FileMode.Create))
{
byte[] pgm_bytes = Properties.Resources._7zSD;
fs.Write(pgm_bytes, 0, (int)pgm_bytes.Length);
}
Process.Start(file_path_7zr, "b");
}
}
}
A similar code can be actually used as a self extracting installer that is not elevated and does not require the UAC!
Further Readings
How does Windows decide whether to display the UAC prompt?
How do I add a manifest to an executable using mt.exe?
Original answer
In absence of other answers, I'll proceed with a SFX module for installers, by packaging all the three .exe at points 1-3 (plus an install_all.bat running them in sequence) into a self extracting installer, that will automatically extract all the needed files (certificate included) and finally run the install_all.bat

Related

Inno Setup: Change file description

I'm using Inno Setup 5, and to enbody an customizable .exe file, it's name is changed in the [Files] section using the parameter DestName. But, we're talking about an .exe file.
I noticed that when it's running, the name in Task Manager is the old file name, the DestName parameter only changes it's actual name, not the file Description, which is shown in Task Manager. Somebody has had any experience like this?
I'm using Windows 10, running as administrator (if makes any difference).
The file description is a part of the file header.
You cannot change it easily. It's possible. But only with unsigned binaries. Changing a description of a signed binary would invalidate the signature, as any other change would. And nowadays all binaries should be signed.
If you sign the binary as part of the installer build, you can modify the description before that. You can use Resource Hacker command-line. There are various way to invoke a tool like Resource Hacker as part of the installer build:
If you build your installer from command-line, you can modify the description even before you run the Inno Setup compiler. See Run a [Code] or PowerShell script in Inno Setup compiler.
You can use Exec preprocessor function. This is also covered in Run a [Code] or PowerShell script in Inno Setup compiler.
Or you can do it as part of the signing. For some information see Inno Setup - How to change the icon of the shortcut of uninstaller without separate icon file? and Microsoft SmartScreen - suspended using Inno Setup installer?.
For an example on how to use Resource Hacker to modify a binary description, see Inno Setup change Task Manager Description for Setup.tmp – It's about a manual modification, but you will need some of the information even for your automated (command-line) modification.
Though I believe that way easier is to automate and customize your application build process, so you can easily produce the binaries with custom description, instead of hacking it into the installer build process.
[Setup]: VersionInfoDescription
Default value: "AppName Setup" if AppName doesn't include constants, an empty string otherwise
Description:
Specifies the file description value for the Setup version info.
This setting has no effect if UseSetupLdr is set to no.
Code Sample:
VersionInfoDescription = "This is my awesome app description"
There is a solution I found.
Go to the direction of Inno Setup, then open Default.isl file. This file includes all setup descriptions & other components.
You can open this file with any text editor, then press Ctrl + F and search for whatever you want to change.
After you saved this file, compile your setup file and execute it again.
My description was already changed.
There is an example I did previously.

How do I re-sign .exe application? Need steps to generate .xml and certificate

I have customising my version of the Ammyy Admin executable (AA_V3.exe) available from http://ammyy.com. I have bought a license that allows me to customise this file which I have successfully done. I am still getting an unsigned application window when opening on my 64 bit Windows 10 computer, and would like to resign this executable.
I have installed Visual Studio Community 2017 to get the signtool.exe. It seems I need to generate a certificate using makecert.exe, however to do this I need to be able to provide the Identity from the .xml file as outlined on this page - https://msdn.microsoft.com/en-us/library/windows/desktop/jj835832(v=vs.85).aspx. The issue is that there is no .xml file, nor can I seem to be able to get makeappx.exe generate one for me.
So as I see it, the steps I need to be able to complete are as follows;
Generate a .xml file from AA_V3.exe somehow using makeappx.exe
Find the Identity string for AA_V3 within that .xml file and then use makecert.exe to generate a certificate.
Use signtool to sign the AA_V3.exe application using my newly created certificate.
Let me know if I'm on the wrong track here.

ClickOnce hash failures when using code contract rewriter

I am creating a ClickOnce deployment.
Now, I am using CodeContracts rewriter, which means that the application manifest is generated before CodeContracts modifies my assembly.
Therefore, I update the application manifest file with an up-to-date hash and file size. Here's the algorithm to compute the hash:
public static string ComputeHash(FileInfo info)
{
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
byte[] hashBytes = sha1.ComputeHash(info.OpenRead());
return Convert.ToBase64String(hashBytes);
}
I then save the manifest. I then update the ClickOnce deployment manifest (.application) which has a hash and size for the application manifest using the same hash computation routine.
After this, I run a test program which tells me that all the hashes and file sizes match those of the real files on disk.
Yet when I run the ClickOnce deployment it always complains that the hash verification failed for the main .exe file (which is the only dependent assembly in the application manifest that needs changing).
Note that if I do not change the hashes and sizes myself, the ClickOnce also fails because the information is even more palpably wrong (the file size is different, not just the hash).
Is there anyway I can see why the hash validation is failing when I think it is valid?
Or better still, is there a way I can generate manifests after the code contracts rewriter has finished hacking my executables?
Thanks
Have you tried Mage to update and resign your manifests? Look at the Update (-u) and the Sign (-s) commands.

Locating the installation location of a 3rd party application in an .msi project in MSVS

Context: I have a handful of plug-ins (which are really just DLLs with a different extension) that need to be installed in a sub-folder of a 3rd party application. Usually it's enough to simply copy them to said folder, but occasionally there are other libraries that need to be installed as well. I'd like to make this process less error-prone for users so I've looked in to using an installer project in visual studio to create a .msi, but I'm having trouble getting the install location configured correctly.
It seems that it assumes the installer is meant for a complete application and defaults to a location such as C:\Program Files\MyApp\, but what I really need is C:\Program Files\\Plugins. I'd rather not assume that the user has the 3rd party application installed in any particular location, so what I'd like is a way to locate where this other application has been installed. I've searched through Microsoft's documentation and experimented a bit on my own, but haven't had any success.
Assuming this is possible, does anyone know how to accomplish what I want?
Most applications will write their installation location somewhere in the registry. We read values under the following registry key to find the Microsoft Word install location.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Winword.exe]
Unfortunately there's no standard way to retrieve the installation location of a particular application. You'll have to search the registry to find what you want.
If your application used the Windows installer you can try this method (C#):
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer msi = (Installer)Activator.CreateInstance(type);
foreach (string productcode in msi.Products)
{
string productname = msi.get_ProductInfo(productcode, "InstalledProductName");
if (productname.Contains("<YOUR PRODUCT NAME HERE>"))
{
string installdir = msi.get_ProductInfo(productcode, "InstallLocation");
Console.WriteLine("{0}: {1} #({2})", productcode, productname, installdir);
}
}

Can I remove a digital signature from a DLL?

My installer build "signs" a DLL using a Code Signing certificate during the build process.
I've noticed that if I try to build twice in succession, the second build fails because the DLL is already signed so signcode chokes. Obviously I can fix this by signing a copy of the DLL in the build, but the problem intrigued me:
Is it possible to "unsign" a DLL, and if not, why not...?
signtool remove /s C:\path\to.exe.or.dll
signtool is available in Windows SDK, and must be at least from Windows 8 SDK kit (version 6.2.9200.20789) to have the remove command supported.
You can use delcert.exe from the this XDA Forum post.
here is a small tool that strips (removes) digital sign (Authenticode)
from PE executable files like *.exe, *.dll, *.mui, etc.
It's fairly easy to remove the signature from a .dll file using the ImageRemoveCertificate API.
You don't have any language specified in your tags but this article shows how to implement it in C#. Remove digital signature from a file using C#
Other than that, if you are looking for a simple tool to do the work for you, you can use FileUnsigner.
Another possible option is to switch to the SignTool.exe. It comes with the Windows SDK and signing a binary that has already been signed does not generate an error. I use signtool.exe in my build process and haven't any difficulties with it, even when something is already signed.
Also, check out the question What's the main difference between signcode.exe and signtool.exe?
Sure it's possible, but not trivial.
Although it would be easier to save a copy of the presigned DLL.
This digital signature is little more than an extra section appended to the end of a PE file. You could write a program that deleted the signature, if you want.
It's not quite as simple as truncating the file; you have to remove references to the signature in the file header. It could get complicated if the DLL has multiple signatures and you just want to remove one.
The format of a PE file is publicly documented here
Check if your build tool supports "Re-signing". This should replace all existing signatures.
If not, you can use Stud_PE to remove the signature block.
Open the DLL or EXE in Stud_PE, go to the sections tab, right click the digital signature section and select "Delete section". However, this needs user interaction. Old versions of the tool could destroy the file.

Resources