代码之家  ›  专栏  ›  技术社区  ›  Cheeso

在Visual Studio安装项目中,如何生成卸载脚本?

  •  27
  • Cheeso  · 技术社区  · 15 年前

    我有一个Visual Studio安装项目。 安装后,它会在应用程序文件夹中创建一个卸载批处理文件。如果用户想要卸载产品,他可以转到“添加/删除程序”,或者双击uninstall.cmd。内容包括:

    %windir%\system32\msiexec /x {CC3EB7BF-DD82-48B9-8EC5-1B0B62B6D285}
    

    guid是来自Visual Studio中安装项目的产品代码。

    ProductCode

    但是,为了使升级正常工作,每次生成新的MSI时,都必须增加版本号。而且,如果我增加版本号,那么我还必须为productcode生成一个新的guid。这意味着静态uninstall.cmd文件需要更改。

    如何在生成时动态生成包含的产品代码的批处理文件?

    8 回复  |  直到 6 年前
        1
  •  65
  •   MPelletier    13 年前

    我找到了这个解决方案 here

    “使用Visual Studio 2005/2008,您不需要编写任何代码来为安装项目添加卸载选项(是的,我知道有些人可以编写代码来执行此操作)

    1)在安装项目中,右键单击目标计算机上的文件系统添加特殊文件夹,选择系统文件夹;

    2)在此系统文件夹中添加一个文件。从本地system32文件夹浏览msiexec.exe并添加它。重写此文件的默认属性,如下所示:

    条件:=未安装(请确保您的安装方式与此完全不同,相同的机箱和所有设备), 永久:=真, 系统:=真, 传递:=真, 生命的:虚伪的

    3)在“用户程序”菜单下新建快捷方式,将“目标”设置为在步骤1中创建的系统文件夹。并将其指向msiexec.exe。重命名快捷方式以卸载应用程序。将arguments属性设置为/x space[productcode]。

    4)构建项目,忽略有关应排除msiexec的警告,不要将其排除,否则安装项目将不会生成。

    未安装条件和永久性:=true确保msiexec.exe仅作为安装的一部分放在系统文件夹中(如果它不存在),并且在卸载时不会将其删除-因此,忽略该警告并继续执行该警告是非常安全的。

    (根据掌门人的描述)

        2
  •  11
  •   Community Egal    7 年前

    我刚做的 this 工作:

    将uninstall.bat文件添加到项目中。文件内容为:

    msiexec.exe /x %1
    

    创建该批处理文件的快捷方式(例如在用户的“程序”菜单中),在快捷方式的“属性”中的“参数”旁边指定: [ProductCode] .

        3
  •  3
  •   Cheeso    15 年前

    这是我编写的创建uninstall.cmd的脚本。它在安装期间作为自定义操作运行。

    var fso, ts;
    var ForWriting= 2;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    
    var parameters = Session.Property("CustomActionData").split("|"); 
    var targetDir = parameters[0];
    var productCode = parameters[1];
    
    ts = fso.OpenTextFile(targetDir + "uninstall.cmd", ForWriting, true);
    
    ts.WriteLine("@echo off");
    ts.WriteLine("goto START");
    ts.WriteLine("=======================================================");
    ts.WriteBlankLines(1);
    ts.WriteLine(" Uninstall.cmd");
    ts.WriteBlankLines(1);
    ts.WriteLine("=======================================================");
    ts.WriteBlankLines(1);
    ts.WriteLine(":START");
    ts.WriteLine("@REM The uuid is the 'ProductCode' in the Visual Studio setup project");
    ts.WriteLine("%windir%\\system32\\msiexec /x " + productCode);
    ts.WriteBlankLines(1);
    ts.Close();
    

    结果是一个始终包含当前产品代码的cmd文件。

    这样做的缺点是什么? 创建uninstall.cmd的脚本 保留在安装目录中。不是什么大问题,但我不喜欢安装目录中的垃圾。我还没有尝试让“createinstaller.js”自动删除。那可能有效。

    编辑 :是,使createinstaller.js自动删除工作正常。

    我要接受我自己的答案!

        4
  •  2
  •   locksmith    12 年前

    批处理文件方法的微小变化。如果不想显示命令窗口,请使用wscript文件。在参数中像以前一样提供[ProductCode]

    <job>
    <?job debug="true" error="true" ?>
    <script language="JScript">
        var arg = [];
        for (var i=0; i<WSH.Arguments.length; i++) {
            arg.push( WSH.Arguments.Item(i) );
        }
    
        if (arg.length>0) {
            var productcode = arg[0];
            var v = new ActiveXObject("Shell.Application");
            v.ShellExecute("msiexec.exe", "/x "+productcode, "", "open", 10);
        }
    
        WSH.Quit(0);
    </script>
    </job>
    
        5
  •  1
  •   Peter    14 年前

    要删除应用程序,我将使用[ProductCode]作为参数,从应用程序本身调用msiexec-有关创建卸载程序的详细指南,请查看此日志: http://endofstream.com/creating-uninstaller-in-a-visual-studio-project/

        6
  •  1
  •   Jela    11 年前

    我意识到这个问题已经得到了解答,但我所做的是创建一个包含以下内容的批处理文件:

    start msiexec.exe /x %1
    

    使用“start”可防止命令提示在卸载过程中保持打开状态,并且在执行批处理文件时,将用传递给该文件的第一个参数替换%1。

    我将批处理文件添加到应用程序文件夹,并创建了指向批处理文件的菜单快捷方式。如果右键单击快捷方式并选择“属性”窗口。在其中,将以下文本添加到arguments属性:

    [ProductCode]
    

    在构建和运行安装程序之后,您将拥有一个开始菜单快捷方式,该快捷方式调用批处理文件并像构建应用程序版本时一样传递产品代码。然后,用户将看到一个提示,询问是否应卸载该产品。

    此解决方案的唯一缺点是,如果用户浏览到应用程序文件夹并双击批处理文件,卸载程序将给出安装包不存在的错误。

        7
  •  1
  •   Merv    6 年前

    我把接受的回答和锁匠的回答结合起来,看不到命令提示符或命令提示符本身的任何闪烁。这样做的一个好处是,你不必创建一个快捷方式,并设置它的参数,以便它工作。

    我的createUninstaller.js文件:

    var fso, ts;
    var ForWriting= 2;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    
    var parameters = Session.Property("CustomActionData").split("|"); 
    var targetDir = parameters[0];
    var productCode = parameters[1];
    
    ts = fso.OpenTextFile(targetDir + "Uninstall.js", ForWriting, true);
    
    ts.WriteLine("var v = new ActiveXObject(\"Shell.Application\");");
    ts.WriteLine("v.ShellExecute(\"msiexec.exe\", \"/x "+productCode+"\", \"\", \"open\",10);");
    ts.Close();
    

    此文件作为自定义操作添加到提交操作“目录”。为了实际执行此自定义操作: 右键单击安装项目>查看>自定义操作>右键单击提交“目录”>添加自定义操作。在必须搜索创建的createUninstaller.js文件并添加它之后。

    现在要使createUninstaller.js读取变量targetDir和productCode,必须
    右键单击安装项目自定义操作中的createUninstaller.js文件。 “提交”目录并转到“属性”窗口。 在属性中,您将看到“CustomActionData”属性。您只需复制粘贴[TargetDir][ProductCode]
    瞧!现在,它应该添加uninstall.js文件,只要双击该文件,它就会工作。

        8
  •  0
  •   Thomas    11 年前

    每次生成设置时,都要更改产品代码。创建一个卸载程序的快捷方式,在那里你会发现命令行参数传递技术来排序剪切。在那里,你总是要写“产品代码”,你总是需要在这里写“产品代码”。

    将此代码放入program.cs文件的主方法中

    [STAThread]
            static void Main()
            {
                bool flag = true;
                string[] arguements = Environment.GetCommandLineArgs();
                foreach (string str in arguements)
                {
                    if ((str.Split('='))[0].ToLower() == "/u")
                    {
                        if (MessageBox.Show("Do you want to uninstall job board", "Are you Sure?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            flag = false;
                            RemoveRegSettings();
                            RemoveIniFile();
                            string guid = str.Split('=')[1];
                            string path = Environment.GetFolderPath(Environment.SpecialFolder.System);
                            ProcessStartInfo si = new ProcessStartInfo(path + @"\msiexec.exe", "/i" + guid);
                            Process.Start(si);
                            Application.Exit();
                            return;
                        }
                    }
                }
                //
    
                //************************************************
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);