从我的自定义操作取消安装

发布于 2024-08-26 02:43:38 字数 122 浏览 4 评论 0原文

我正在使用 Windows Installer(而不是 wix)为我的程序编写安装程序。 在某些情况下,我想从自定义操作中取消安装过程。此外,我想在我的文本中显示一条错误消息。 这怎么办?

C#、.net 3.5

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

终难遇 2024-09-02 02:43:38

您可以通过创建错误自定义操作来执行此操作。将错误自定义操作的条件设置为失败条件(如果条件评估为 true,则安装将失败)并将消息设置为您的自定义文本。

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.

Oo萌小芽oO 2024-09-02 02:43:38

对我来说工作:

上下文:出于某种原因,我需要检查用户是否安装了 3.5SP1,如果没有,则取消安装并重定向到正确的下载页面。

步骤一:
像这样修改你的安装程序

    [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);
    }

第2步:
使用该代码托管您的 MessageBox(我把它带到其他地方,没有时间自己找到它)

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;
    }
}

第 3 步:
杀死 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);
}

用勺子而不是摇酒器将其混合并食用;)

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 ;)

怪我闹别瞎闹 2024-09-02 02:43:38

只需从自定义操作中返回 ERROR_INSTALL_USEREXIT 即可。

http://msdn.microsoft。 com/en-us/library/windows/desktop/aa368072(v=vs.85).aspx

请参阅以下链接了解如何显示错误消息:

http://msdn.microsoft.com/en-us/library/windows/desktop /aa371247(v=vs.85).aspx

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

内心荒芜 2024-09-02 02:43:38

在任何时候,您认为需要中止:

throw new InstallException("This user name doesn't exist in this system!.");

安装程序将弹出“用户中止”对话框,其中包含异常消息。

At any point you consider you need to abort just:

throw new InstallException("This user name doesn't exist in this system!.");

The installer will popup the User Aborted dialog with your Exception message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文