Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 静默卸载ClickOnce应用程序_Batch File_Clickonce_Uninstallation - Fatal编程技术网

Batch file 静默卸载ClickOnce应用程序

Batch file 静默卸载ClickOnce应用程序,batch-file,clickonce,uninstallation,Batch File,Clickonce,Uninstallation,我们有一个使用VisualStudio内置的ClickOnce部署工具部署的生产应用程序。我正在编写批处理文件以卸载应用程序: rundll32.exe dfshim.dll,ShArpMaintain AppName.application, Culture=neutral, PublicKeyToken=XXXXXX, processorArchitecture=x86 批处理文件工作,并调用应用程序的卸载。然而,我希望能默默地做到这一点。我试过/Q/Q/S/S/Silent,但没有任何乐

我们有一个使用VisualStudio内置的ClickOnce部署工具部署的生产应用程序。我正在编写批处理文件以卸载应用程序:

rundll32.exe dfshim.dll,ShArpMaintain AppName.application, Culture=neutral,
PublicKeyToken=XXXXXX, processorArchitecture=x86
批处理文件工作,并调用应用程序的卸载。然而,我希望能默默地做到这一点。我试过
/Q/Q/S/S/Silent
,但没有任何乐趣

我该怎么做



我不想隐藏批处理文件窗口。只有“ClickOnce”窗口。

您可以尝试使用。

您不能取消ClickOnce应用程序的卸载对话框。您可以编写一个小应用程序来卸载ClickOnce应用程序,并以编程方式点击对话框上的按钮,因此用户无需执行任何操作。这是您所能做的最好的了。

不要让它过于复杂,保持简单-这在
Windows XP和7上都有效:

转到
添加/删除程序
,记下程序的确切名称。 打开
Notepad
并粘贴以下文本:

wmic产品,其中name=“PROGRAM name”卸载


但请确保在引号之间键入程序的确切名称,然后选择“另存为/所有文件”,并将文件命名为“Uninstall.bat”
,然后对其进行测试,以确保其工作正常。

由于似乎没有很好的解决方案,我实现了一个新的ClickOnce卸载程序。它可以通过命令行、从.NET调用,也可以作为自定义操作集成到WiX安装项目中

我们在Wunderlist 2.1版本中使用了它,在该版本中,我们从ClickOnce切换到了Windows Installer软件包。它集成到安装过程中,对用户完全透明。

我可以确认,这对ClickOnce应用程序不起作用。他们只是没有列在那里

我想把这个放在这里,因为我一直在寻找解决这个问题的方法,但一直没有找到一个完整的解决方案

我对整个程序设计都比较陌生,但我认为这可以给我们提供一些如何进行的想法

它基本上验证应用程序当前是否正在运行,如果正在运行,则会终止它。然后它检查注册表以找到卸载字符串,将其放入批处理文件中,并等待进程结束。然后它会发送密钥以自动同意卸载。就这样

namespace MyNameSpace
{
    public class uninstallclickonce
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]

        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [System.Runtime.InteropServices.DllImport("user32.dll")]

        private static extern bool SetForegroundWindow(IntPtr hWnd);

        private Process process;
        private ProcessStartInfo startInfo;

        public void isAppRunning()
        {
            // Run the below command in CMD to find the name of the process
            // in the text file.
            //
            //     WMIC /OUTPUT:C:\ProcessList.txt PROCESS get Caption,Commandline,Processid
            //
            // Change the name of the process to kill
            string processNameToKill = "Auto-Crop"; 

            Process [] runningProcesses = Process.GetProcesses();

            foreach (Process myProcess in runningProcesses)
            {
                // Check if given process name is running
                if (myProcess.ProcessName == processNameToKill)
                {
                    killAppRunning(myProcess);
                }
            }
        }

        private void killAppRunning(Process myProcess)
        {
            // Ask the user if he wants to kill the process
            // now or cancel the installation altogether
            DialogResult killMsgBox =
                MessageBox.Show(
                    "Crop-Me for OCA must not be running in order to get the new version\nIf you are ready to close the app, click OK.\nClick Cancel to abort the installation.",
                    "Crop-Me Still Running",
                    MessageBoxButtons.OKCancel,
                    MessageBoxIcon.Question);

            switch(killMsgBox)
            {
                case DialogResult.OK:
                    //Kill the process
                    myProcess.Kill();
                    findRegistryClickOnce();
                    break;
                case DialogResult.Cancel:
                    //Cancel whole installation
                    break;
            }
        }

        private void findRegistryClickOnce()
        {
            string uninstallRegString = null; // Will be ClickOnce Uninstall String
            string valueToFind = "Crop Me for OCA"; // Name of the application we want
                                                    // to uninstall (found in registry)
            string keyNameToFind = "DisplayName"; // Name of the Value in registry
            string uninstallValueName = "UninstallString"; // Name of the uninstall string

            //Registry location where we find all installed ClickOnce applications
            string regProgsLocation = 
                "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";

            using (RegistryKey baseLocRegKey = Registry.CurrentUser.OpenSubKey(regProgsLocation))
            {
                //Console.WriteLine("There are {0} subkeys in here", baseLocRegKey.SubKeyCount.ToString());

                foreach (string subkeyfirstlevel in baseLocRegKey.GetSubKeyNames())
                {
                   //Can be used to see what you find in registry
                   // Console.WriteLine("{0,-8}: {1}", subkeyfirstlevel, baseLocRegKey.GetValueNames());

                    try
                    {
                        string subtest = baseLocRegKey.ToString() + "\\" + subkeyfirstlevel.ToString();

                        using (RegistryKey cropMeLocRegKey =
                                 Registry.CurrentUser.OpenSubKey(regProgsLocation + "\\" + subkeyfirstlevel))
                        {
                            //Can be used to see what you find in registry
                            //  Console.WriteLine("Subkey DisplayName: " + cropMeLocRegKey.GetValueNames());

                            //For each
                            foreach (string subkeysecondlevel in cropMeLocRegKey.GetValueNames())
                            {
                                // If the Value Name equals the name application to uninstall
                                if (cropMeLocRegKey.GetValue(keyNameToFind).ToString() == valueToFind)
                                {
                                    uninstallRegString = cropMeLocRegKey.GetValue(uninstallValueName).ToString();

                                    //Exit Foreach
                                    break;
                                }
                            }
                        }
                    }
                    catch (System.Security.SecurityException)
                    {
                        MessageBox.Show("security exception?");
                    }
                }
            }
            if (uninstallRegString != null)
            {
                batFileCreateStartProcess(uninstallRegString);
            }
        }

        // Creates batch file to run the uninstall from
        private void batFileCreateStartProcess(string uninstallRegstring)
        {
            //Batch file name, which will be created in Window's temps foler
            string tempPathfile = Path.GetTempPath() + "cropmeuninstall.bat";

            if (!File.Exists(@tempPathfile))
            {
                using (FileStream createfile = File.Create(@tempPathfile))
                {
                    createfile.Close();
                }
            }

            using (StreamWriter writefile = new StreamWriter(@tempPathfile))
            {
                //Writes our uninstall value found earlier in batch file
                writefile.WriteLine(@"Start " + uninstallRegstring);
            }

            process = new Process();
            startInfo = new ProcessStartInfo();

            startInfo.FileName = tempPathfile;
            process.StartInfo = startInfo;
            process.Start();
            process.WaitForExit();

            File.Delete(tempPathfile); //Deletes the file

            removeClickOnceAuto();
        }

        // Automation of clicks in the uninstall to remove the
        // need of any user interactions
        private void removeClickOnceAuto()
        {
            IntPtr myWindowHandle = IntPtr.Zero;

            for (int i = 0; i < 60 && myWindowHandle == IntPtr.Zero; i++)
            {
                Thread.Sleep(1500);

                myWindowHandle = FindWindow(null, "Crop Me for OCA Maintenance");
            }

            if (myWindowHandle != IntPtr.Zero)
            {
                SetForegroundWindow(myWindowHandle);

                SendKeys.Send("+{TAB}"); // Shift + TAB
                SendKeys.Send("{ENTER}");
                SendKeys.Flush();
            }
        }
    }
}
名称空间MyNameSpace
{
公共类卸载ClickOnce
{
[System.Runtime.InteropServices.DllImport(“user32.dll”)]
私有静态外部IntPtr FindWindow(字符串lpClassName,字符串lpWindowName);
[System.Runtime.InteropServices.DllImport(“user32.dll”)]
私有静态外部bool setforegroundindow(IntPtr hWnd);
私有过程;
私有进程startInfo startInfo;
public void isAppRunning()
{
//在CMD中运行以下命令以查找进程的名称
//在文本文件中。
//
//WMIC/OUTPUT:C:\ProcessList.txt进程获取标题、命令行、进程ID
//
//将进程的名称更改为kill
字符串processNameToKill=“自动裁剪”;
Process[]runningProcesses=Process.GetProcesses();
foreach(运行流程中的流程myProcess)
{
//检查给定的进程名是否正在运行
if(myProcess.ProcessName==processNameToKill)
{
killAppRunning(myProcess);
}
}
}
私有无效基拉普运行(进程myProcess)
{
//询问用户是否要终止进程
//现在或完全取消安装
DialogResult killMsgBox=
MessageBox.Show(
“要获得新版本,必须不运行Crop Me for OCA。\n如果准备关闭应用程序,请单击“确定”。\n单击“取消”中止安装。”,
“我还在跑”,
MessageBoxButtons.ok取消,
MessageBoxIcon.Question);
开关(killMsgBox)
{
case DialogResult.OK:
//终止进程
myProcess.Kill();
FindRegistryClickKonce();
打破
案例对话框结果。取消:
//取消整个安装
打破
}
}
私有无效FindRegistryClickKonce()
{
string uninstallRegString=null;//卸载字符串后将被单击
string valueToFind=“为OCA裁剪我”;//我们需要的应用程序的名称
//要卸载(在注册表中找到)
string keyname tofind=“DisplayName”;//注册表中值的名称
string uninstallValueName=“UninstallString”;//卸载字符串的名称
//找到所有已安装ClickOnce应用程序的注册表位置
字符串regProgsLocation=
“软件\\Microsoft\\Windows\\CurrentVersion\\Uninstall”;
使用(RegistryKey baseLocRegKey=Registry.CurrentUser.OpenSubKey(regProgsLocation))
{
//WriteLine(“这里有{0}个子键”,baseLocRegKey.SubKeyCount.ToString());
foreach(baseLocRegKey.GetSubKeyNames()中的字符串subkeyfirstlevel)
{
//可用于查看您在注册表中找到的内容
//WriteLine(“{0,-8}:{1}”,subkeyfirstlevel,baseLocalRegKey.GetValueNames());
尝试
{
string subtest=baseLocRegKey.ToString()+“\\”+subkeyfirstlevel.ToString();
使用(注册表项cropMeLocRegKey)=
Registry.CurrentUser.exe打开