尝试为所有用户安装软件时,如何检查软件是否仅由用户级别的其他人安装?
How to check if a software is only installed by other at user level when trying to install it for all users?
我正在尝试创建我的安装程序,让用户既可以为每个用户安装,也可以为所有用户安装。
现在假设 John 已经在用户级别安装了该软件,然后 Andy 试图在同一系统上将其作为机器级别安装,我如何才能检测到它已经在 john 的用户级别安装并卸载还是中止安装?
因为我在机器级别和用户级别安装时具有不同的功能。我不想在机器上出现冲突情况。
理想情况下,我想检查软件是否安装在用户级别,然后在机器级别安装时从用户级别安装它。
我正在使用 InstallShield 2016 创建安装程序。
Admin Rights: You need to run the below with admin rights for it to work. Launch Visual Studio with admin rights (right click shortcut
and go run as adminstrator).
检索每用户安装:没有时间正确清理它,相当"dog's breakfast"在混合各种字符串类型方面,我从 github.com 片段中将其涂抹在一起,但这似乎可以找到指定的 user SID[的每个用户安装] =36=]:
#include "pch.h"
#include <windows.h>
#include "msi.h" // Windows Installer
#include <atlstr.h> // ATL CString
#pragma comment (lib, "msi.lib")
int main()
{
//
// Admin rights required!
//
UINT result = 0;
DWORD dwIndex = 0;
TCHAR szInstalledProductCode[39] = { 0 };
TCHAR szSid[128] = { 0 };
DWORD cchSid;
MSIINSTALLCONTEXT dwInstalledContext;
DWORD cchProductName = MAX_PATH + 1;
WCHAR* lpProductName = new WCHAR[cchProductName];
// Fake, sample SID. Replace:
CString userSID = _T("S-1-5-21-6780625448-452764730-4189743271-1542");
while (ERROR_SUCCESS == (result = MsiEnumProductsEx(NULL, userSID, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED, dwIndex, szInstalledProductCode, &dwInstalledContext, szSid, &cchSid)))
{
UINT uiReturn = MsiGetProductInfoEx(szInstalledProductCode, userSID, dwInstalledContext, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, lpProductName, &cchProductName);
MessageBox(NULL, _T("Product Code: ") + (CString)szInstalledProductCode + _T("\r\n\r\nProduct Name: ") + lpProductName, _T("Product Name:"), MB_OK);
dwIndex++;
}
return 0;
}
程序:在上面的工作有任何希望之前,你需要做一些事情。
- 只需创建一个 Visual C++ 控制台项目。我用的是 Visual Studio 2017.
- 确定您要检索其每个用户包的帐户的用户 SID。您可以从命令行使用
whoami /user
,如下所述:How to get active session user SID?
- 更改
CString userSID = "S-1-5-21-etc..."
行以从您的系统中检索有问题的用户 SID。
为了从系统中获取用户 SID 列表,我不确定该怎么做。如果你有好的方法欢迎分享。
VBScripting 也有可用的方法和属性,我也尝试过,但我无法检索其他用户的程序包。我可能只是缺少一些参数,我不确定。
这对我有用。感谢 Stein Åsmul。
#include <windows.h>
#include "msi.h" // Windows Installer
#include <tchar.h> // ATL CString
#pragma comment (lib, "msi.lib")
int main()
{
//
// Admin rights required!
//
TCHAR * userSID = _T("s-1-1-0");
UINT result = 0;
DWORD dwIndex = 0;
MSIINSTALLCONTEXT dwInstalledContext;
DWORD cchProductName = 2000;
WCHAR lpProductName[2000] = { 0 };
while (true)
{
TCHAR szInstalledProductCode[100] = { 0 };
TCHAR szSid[1000] = { 0 };
DWORD cchSid = 1000;
if (ERROR_SUCCESS != (result = MsiEnumProductsEx(NULL, userSID, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED, dwIndex, szInstalledProductCode, &dwInstalledContext, szSid, &cchSid)))
{
long lVal = GetLastError();
_tprintf(_T("MsiEnumProductsEx LastError : %d, \r\n\r result: %d\n"), cchSid, result);
break;
}
UINT uiReturn = MsiGetProductInfoEx(szInstalledProductCode, szSid, dwInstalledContext, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, lpProductName, &cchProductName);
_tprintf(_T("Product Code: %s, \r\n\r\nProduct Name: %s\n"), szInstalledProductCode, lpProductName);
if (uiReturn != ERROR_SUCCESS)
{
long lVal = GetLastError();
_tprintf(_T(" MsiGetProductInfoEx LastError : %d, \r\n\r result: %d\n"), cchProductName, uiReturn);
}
dwIndex++;
}
return 0;
}
我正在尝试创建我的安装程序,让用户既可以为每个用户安装,也可以为所有用户安装。
现在假设 John 已经在用户级别安装了该软件,然后 Andy 试图在同一系统上将其作为机器级别安装,我如何才能检测到它已经在 john 的用户级别安装并卸载还是中止安装?
因为我在机器级别和用户级别安装时具有不同的功能。我不想在机器上出现冲突情况。
理想情况下,我想检查软件是否安装在用户级别,然后在机器级别安装时从用户级别安装它。
我正在使用 InstallShield 2016 创建安装程序。
Admin Rights: You need to run the below with admin rights for it to work. Launch Visual Studio with admin rights (right click shortcut and go run as adminstrator).
检索每用户安装:没有时间正确清理它,相当"dog's breakfast"在混合各种字符串类型方面,我从 github.com 片段中将其涂抹在一起,但这似乎可以找到指定的 user SID[的每个用户安装] =36=]:
#include "pch.h"
#include <windows.h>
#include "msi.h" // Windows Installer
#include <atlstr.h> // ATL CString
#pragma comment (lib, "msi.lib")
int main()
{
//
// Admin rights required!
//
UINT result = 0;
DWORD dwIndex = 0;
TCHAR szInstalledProductCode[39] = { 0 };
TCHAR szSid[128] = { 0 };
DWORD cchSid;
MSIINSTALLCONTEXT dwInstalledContext;
DWORD cchProductName = MAX_PATH + 1;
WCHAR* lpProductName = new WCHAR[cchProductName];
// Fake, sample SID. Replace:
CString userSID = _T("S-1-5-21-6780625448-452764730-4189743271-1542");
while (ERROR_SUCCESS == (result = MsiEnumProductsEx(NULL, userSID, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED, dwIndex, szInstalledProductCode, &dwInstalledContext, szSid, &cchSid)))
{
UINT uiReturn = MsiGetProductInfoEx(szInstalledProductCode, userSID, dwInstalledContext, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, lpProductName, &cchProductName);
MessageBox(NULL, _T("Product Code: ") + (CString)szInstalledProductCode + _T("\r\n\r\nProduct Name: ") + lpProductName, _T("Product Name:"), MB_OK);
dwIndex++;
}
return 0;
}
程序:在上面的工作有任何希望之前,你需要做一些事情。
- 只需创建一个 Visual C++ 控制台项目。我用的是 Visual Studio 2017.
- 确定您要检索其每个用户包的帐户的用户 SID。您可以从命令行使用
whoami /user
,如下所述:How to get active session user SID? - 更改
CString userSID = "S-1-5-21-etc..."
行以从您的系统中检索有问题的用户 SID。
为了从系统中获取用户 SID 列表,我不确定该怎么做。如果你有好的方法欢迎分享。
VBScripting 也有可用的方法和属性,我也尝试过,但我无法检索其他用户的程序包。我可能只是缺少一些参数,我不确定。
这对我有用。感谢 Stein Åsmul。
#include <windows.h>
#include "msi.h" // Windows Installer
#include <tchar.h> // ATL CString
#pragma comment (lib, "msi.lib")
int main()
{
//
// Admin rights required!
//
TCHAR * userSID = _T("s-1-1-0");
UINT result = 0;
DWORD dwIndex = 0;
MSIINSTALLCONTEXT dwInstalledContext;
DWORD cchProductName = 2000;
WCHAR lpProductName[2000] = { 0 };
while (true)
{
TCHAR szInstalledProductCode[100] = { 0 };
TCHAR szSid[1000] = { 0 };
DWORD cchSid = 1000;
if (ERROR_SUCCESS != (result = MsiEnumProductsEx(NULL, userSID, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED, dwIndex, szInstalledProductCode, &dwInstalledContext, szSid, &cchSid)))
{
long lVal = GetLastError();
_tprintf(_T("MsiEnumProductsEx LastError : %d, \r\n\r result: %d\n"), cchSid, result);
break;
}
UINT uiReturn = MsiGetProductInfoEx(szInstalledProductCode, szSid, dwInstalledContext, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, lpProductName, &cchProductName);
_tprintf(_T("Product Code: %s, \r\n\r\nProduct Name: %s\n"), szInstalledProductCode, lpProductName);
if (uiReturn != ERROR_SUCCESS)
{
long lVal = GetLastError();
_tprintf(_T(" MsiGetProductInfoEx LastError : %d, \r\n\r result: %d\n"), cchProductName, uiReturn);
}
dwIndex++;
}
return 0;
}