静默卸载所有以前的 MS Office 软件

Posted

技术标签:

【中文标题】静默卸载所有以前的 MS Office 软件【英文标题】:Silently Uninstall ALL previous MS Office Software 【发布时间】:2015-09-23 13:17:40 【问题描述】:

我正在尝试以静默方式卸载所有以前的 Microsoft 软件,以便运行 vbscript 来安装 Office 365(有效)。

这是目前有效的。 使用此处的脚本: https://marckean.wordpress.com/2013/06/18/fully-automate-removal-of-any-version-office-in-preparation-for-office-365/ 从这个链接我使用 OffScrub7.vbs & OffScrub10.vbs 理论上卸载所有 Office 2010 产品和所有 Office 2007 产品,但事实并非如此!

运行上述卸载脚本后,它们仍会离开 Lync 2010 和 MS Access Database 2007(32 位)。

什么是确保卸载所有以前的办公产品的最佳方法,包括上述未被 OffScrub7.vbs 和 OffScrub10.vbs 卸载的软件?我的猜测是找到静默 vbscripts 来卸载 Lync 2010 和 MS Access Database 2007(32 位)?

【问题讨论】:

我错了,使用上面链接中的 .bat 文件运行 BOTH Officesrub10 和 07 作品。 【参考方案1】:

所有微软应用都可以使用简单的 c++ 代码和 msi api 卸载。

要求:win 7 pro 适用于 32 位和 64 位操作系统。

一个迷你工具.exe,可以包装在vb脚本、PowerShell等中

更新:

我有一点空闲时间。 我想补充一下我的答案。

我讲了一个小应用程序,但没有显示一行代码。

现在我们将纠正这个问题。

1) 需要 Win7 Pro,64 位或 32 位,没关系。 项目我们要编译一个32位的编译器,因为我们的应用需要运行在32位和64位的操作系统上。

2) 需要任何 Ide,我建议 Code :: Blocks。

3) 需要 mingv32-w64 编译器 - 更多信息在这里 -- mingw-w64.org

3.1) 64位和32位操作系统需要安装两个版本的编译器,即使你有32作为主机运行。我们需要一个来自 64 位编译器安装的静态库。

4) 创建控制台应用程序

5) 项目的构建选项 - 添加静态库项目 libmsi.a

但是!在32位安装的编译器只有头文件mhi.n,而库本身没有! 但它在安装程序的 64 位版本中。 在 64 位编译器安装的 Lib 文件夹中找到这个静态库。

6) 代码 - 枚举应用程序(来源:http://mariusbancila.ro/blog/2011/05/01/finding-installed-applications-with-vc/)

该实用程序必须以管理员权限运行。

也就是说,如果我们从 powershell 脚本运行该实用程序,那么 powershell 应该以管理员权限运行。

#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <msi.h>
#include <string>

using namespace std;

string MsiQueryProperty(LPCTSTR szProductCode,
                     LPCTSTR szUserSid,
                     MSIINSTALLCONTEXT dwContext,
                     LPCTSTR szProperty)

    string value;
    DWORD cchValue = 0;
    UINT ret2 = ::MsiGetProductInfoEx(
        szProductCode,
        szUserSid,
        dwContext,
        szProperty,
        NULL,
        &cchValue);
    if(ret2 == ERROR_SUCCESS)
    
        cchValue++;
        value.resize(cchValue);
        ret2 = ::MsiGetProductInfoEx(
            szProductCode,
            szUserSid,
            dwContext,
            szProperty,
            (LPTSTR)&value[0],
            &cchValue);
    
    return value;


void MsiEnum()

    UINT ret = 0;
    DWORD dwIndex = 0;
    TCHAR szInstalledProductCode[39] = 0;
    TCHAR szSid[128] = 0;
    DWORD cchSid;
    MSIINSTALLCONTEXT dwInstalledContext;
    do
    
        memset(szInstalledProductCode, 0, sizeof(szInstalledProductCode));
        cchSid = sizeof(szSid)/sizeof(szSid[0]);
        ret = ::MsiEnumProductsEx(
            NULL,           // all the products in the context
            _T("s-1-1-0"),  // i.e.Everyone, all users in the system
            MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE,
            dwIndex,
            szInstalledProductCode,
            &dwInstalledContext,
            szSid,
            &cchSid);
        if(ret == ERROR_SUCCESS)
        
            string name = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_INSTALLEDPRODUCTNAME);
            string publisher = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_PUBLISHER);
            string version = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_VERSIONSTRING);
            string location = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_INSTALLLOCATION);

            cout << name << endl;
            cout << "  - " << publisher << endl;
            cout << "  - " << version << endl;
            cout << "  - " << location << endl;
            cout << endl;
            dwIndex++;
        
    
    while(ret == ERROR_SUCCESS);


int main()

    MsiEnum();
    return 0;

过一段时间会添加代码,删除代表他的应用程序,这会显示在控制面板的已安装程序列表中。

时间不够,伤心=(

但你可以尝试写一个应用程序(如果你有兴趣,真的没什么花哨的,但仍然很有趣)

【讨论】:

以上是关于静默卸载所有以前的 MS Office 软件的主要内容,如果未能解决你的问题,请参考以下文章

office2010无法卸载问题

如何实现在安装新版软件的同时静默卸载掉电脑里指定的一款软件?谢谢!

安装visio,提示必须卸载所有32位的软件

如何用bat文件定期卸载软件?

关于NSIS静默安装在控制面板上自定义卸载图标?

已经安装32位的office,需要卸载掉才可以安装64位的吗