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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1356160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 10:56:19  来源:igfitidea点击:

In a Visual Studio setup project, How do I generate an uninstall script?

visual-studiovisual-studio-2008installationsetup-project

提问by Cheeso

I have a Visual Studio setup project. Upon installation, it creates an uninstall batch file in the application folder. IF the user wants to uninstall the product, he can go to "Add/Remove Programs", or he can just double-click the uninstall.cmd. The contents are:

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

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

The GUID there is the ProductCode from the Setup Project in Visual Studio.

GUID 是 Visual Studio 中安装项目的 ProductCode。

ProductCode

产品代码

But, in order for upgrades to work properly, I have to increment the Version number, every time I produce a new MSI. And, if I increment the Version number, then I also have to generate a new Guid for the ProductCode. Which means the static uninstall.cmd file needs to change.

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

How can I dynamically generate a batch file that contains the ProductCode for the, at build time?

如何在构建时动态生成包含 ProductCode 的批处理文件?

采纳答案by Cheeso

This is the script I wrote that creates an uninstall.cmd. It runs as a custom action during installation.

这是我编写的用于创建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();

The result is a cmd file that always has the current ProductCode in it.

结果是一个 cmd 文件,其中始终包含当前的 ProductCode。

The downside of this is that ?the script that creates the uninstall.cmdremains in the installation directory. Not a huge problem but I don't like the rubbish in the install directory. I haven't yet tried to make the "createInstaller.js" self-deleting. That might work.

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

EDIT: yes, making the createInstaller.js self-deleting works fine.

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

I'm going to accept my own answer!

我要接受我自己的答案!

回答by Ben

I found this solution here

我在这里找到了这个解决方案

"Using Visual Studio 2005/2008, you don't need to write any code to add a uninstall option for a Setup project (Yes I know some people can write code to do it)

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

1) In the Setup Project –> File System windows –> Right Click “File System on Target machine” –> add a Special Folder, select System Folder;

1) 在Setup Project –> File System windows –> 右击“File System on Target machine” –> 添加一个特殊文件夹,选择System Folder;

2) Into this system folder Add a file. Browse for msiexec.exe from local System32 folder and add it. Override default properties of this file as follows:

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

Condition:=Not Installed (make sure you put ‘Not Installed' exactly like that, same case and everything), Permanent:=True, System:=True, Transitive:=True, Vital:=False.

条件:=未安装(确保您将“未安装”完全相同,大小写相同),永久:=真,系统:=真,传递:=真,重要:=假。

3) Create a new shortcut under the ‘Users Program Menu', Set Target to the System Folder which you created in the step 1. and point it's at the msiexec.exe. Rename the shortcut to ‘Uninstall Your Application'. Set the Arguments property to /x{space}[ProductCode].

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

4) Build the project, ignore warning about the fact that msiexec should be excluded, DONT exclude it or the setup project wont build.

4)构建项目,忽略关于应该排除 msiexec 的警告,不要排除它或安装项目不会构建。

The ‘Not Installed' condition and Permananet:=True ensure that the msiexec.exe is only placed into the system folder as part of the install IF it doesn't aready exist, and it is not removed on an uninstall - therefore it;s pretty safe to ignore that warning and just go for it.

“未安装”条件和 Permananet:=True 确保 msiexec.exe 仅作为安装的一部分放入系统文件夹中,如果它不存在,并且不会在卸载时删除 - 因此它;s忽略该警告并继续执行非常安全。

(Based on the description from SlapHead)"

(根据 SlapHead 的描述)”

回答by MPelletier

I just made thiswork:

我刚刚完成了这项工作:

Add an uninstall.bat file to your project. The file contents is:

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

msiexec.exe /x %1

Make a shortcut to that batch file (say in User's Program Menu), specify in the shortcut's properties, next to Arguments: [ProductCode].

制作该批处理文件的快捷方式(例如在用户的程序菜单中),在快捷方式的属性中指定,在 Arguments: 旁边[ProductCode]

回答by locksmith

a slight variation on the batch file approach. if you don't want to show a command window, use a wscript file. supply [ProductCode] as before in Arguments

批处理文件方法的细微变化。如果不想显示命令窗口,请使用 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>

回答by Jela

I realize this question has already been answered, but what I did was create a batch file with the following content:

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

start msiexec.exe /x %1

Using "start" prevents the command prompt from staying open during the uninstallation process and the %1 is replaced by the first argument you pass to the batch file when executing it.

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

I added the batch file to the application folder and created a menu shortcut that points to the batch file. If you right click the shortcut and select Properties Window. In there, add the following text to the Arguments property:

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

[ProductCode]

After building and running the installer, you'll have a start menu shortcut that calls the batch file and passes the product code as it was when that version of the application was built. The user will then see a prompt asking if the product should be uninstalled.

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

The only downside of this solution is that if the user browses to the application folder and double clicks the batch file, the uninstaller will give an error that the install package does not exist.

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

回答by Merv

I did a combination of the accepted answer and Locksmith's answer to not see any flashes of command prompt or the command prompt itself. One pro of doing it like this is that you DONT HAVE to create a shortcut and set the arguments for it in order for it to work.

我将接受的答案和 Locksmith 的答案结合起来,看不到任何命令提示符或命令提示符本身的闪烁。这样做的一个优点是您不必创建快捷方式并为其设置参数以使其工作。

My createUninstaller.js file:

我的 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();

This file is added as a custom action at the commit action 'directory'. In order to actually get to this custom actions: right click your setup project>view>custom actions>right click commit 'directory'>add custom action. After you have to search for the createUninstaller.js file you created and add it.

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

Now to make the createUninstaller.js read the variables targetDir and productCode you have to
Right click the createUninstaller.js file in the setup project custom action 'commit' directory and go to properties window. In properties you will see the 'CustomActionData' property. In there you just copy paste [TARGETDIR]|[ProductCode]
And VOILA! It should now add the Uninstall.js file which will work as soon as you double click it.

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

回答by Peter

For removing the application I would use the [ProductCode] as a parameter, calling the msiexec from within the application itself - for a detailed guide as to creating the uninstaller please check this blog: http://endofstream.com/creating-uninstaller-in-a-visual-studio-project/

为了删除应用程序,我将使用 [ProductCode] 作为参数,从应用程序本身内部调用 msiexec - 有关创建卸载程序的详细指南,请查看此博客:http: //endofstream.com/creating-uninstaller-视觉工作室项目/

回答by Thomas

every time when u generate setup then always change product code. create a uninstaller shortcut and there u will find command line argument passing technique to sort cut. there u will write always "/u product code" product code u need to write here always.

每次当您生成设置时,请始终更改产品代码。创建一个卸载程序快捷方式,你会在那里找到命令行参数传递技术来排序剪切。在那里你会一直写“/u product code”你需要在这里写的产品代码。

put this code in main method of program.cs file

将此代码放在 program.cs 文件的 main 方法中

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