问题
I'm writing installer for my program using Windows Installer (not wix). In some cases i want cancel installation proccess from my custom action. Beside, i want show an error message with my text. How do this?
C#, .net 3.5
回答1:
You can do this by creating an error custom action. Set the condition of the error custom action to be the fail condition (if the condition evaluates to true, the installation will fail) and set the message to your custom text.
回答2:
Working thing for me:
Context: for some reason I need to check if the user has 3.5SP1 installed, cancel the install and redirect to the correct download page if not.
Step1: Modify your installer like this
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Install(IDictionary stateSaver)
{
//Check if the FrameWork 3.5SP1 is installed
if (mycondition)
{
//3.5SP1 is installed, ask for framework install
if (TopMostMessageBox.Show("body", "title", MessageBoxButtons.YesNo) == DialogResult.Yes)
System.Diagnostics.Process.Start("http://Microsoft FRW Link");
WindowHandler.Terminate();
}
else
base.Install(stateSaver);
}
Step2: Use that code to host your MessageBox (I took it elsewhere, no time to find it by myself)
static public class TopMostMessageBox
{
static public DialogResult Show(string message)
{
return Show(message, string.Empty, MessageBoxButtons.OK);
}
static public DialogResult Show(string message, string title)
{
return Show(message, title, MessageBoxButtons.OK);
}
static public DialogResult Show(string message, string title,
MessageBoxButtons buttons)
{
// Create a host form that is a TopMost window which will be the
// parent of the MessageBox.
Form topmostForm = new Form();
// We do not want anyone to see this window so position it off the
// visible screen and make it as small as possible
topmostForm.Size = new System.Drawing.Size(1, 1);
topmostForm.StartPosition = FormStartPosition.Manual;
System.Drawing.Rectangle rect = SystemInformation.VirtualScreen;
topmostForm.Location = new System.Drawing.Point(rect.Bottom + 10,
rect.Right + 10);
topmostForm.Show();
// Make this form the active form and make it TopMost
topmostForm.Focus();
topmostForm.BringToFront();
topmostForm.TopMost = true;
// Finally show the MessageBox with the form just created as its owner
DialogResult result = MessageBox.Show(topmostForm, message, title,
buttons);
topmostForm.Dispose(); // clean it up all the way
return result;
}
}
Step3: Kill the msiexec
internal static class WindowHandler
{
internal static void Terminate()
{
var processes = Process.GetProcessesByName("msiexec").OrderBy(x => x.StartTime); \\DO NOT FORGET THE ORDERBY!!! It makes the msi processes killed in the right order
foreach (var process in processes)
{
var hWnd = process.MainWindowHandle.ToInt32();
ShowWindow(hWnd, 0); //This is to hide the msi window and only show the popup
try
{
process.Kill();
}
catch
{
}
}
}
[DllImport("User32")]
private static extern int ShowWindow(int hwnd, int nCmdShow);
}
Mix it with a spoon not with a shaker and serve ;)
回答3:
Just return ERROR_INSTALL_USEREXIT from your custom action.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa368072(v=vs.85).aspx
Please see the following link on how to display an error message:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa371247(v=vs.85).aspx
来源:https://stackoverflow.com/questions/2454456/cancel-installation-from-my-custom-action