检索Windows 7,8和10上所有当前安装的软件

时间:2019-01-29 02:24:31

标签: java windows powershell windows-10

我基本上需要检索Windows(7,8,10)中当前安装的 all 软件的nameversioninstall_date

我找到了:

String command = "powershell.exe Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | DisplayName, DisplayVersion, InstallDate | ConvertTo-Json";

Process powerShellProcess = Runtime.getRuntime().exec(command);

但这不是真的。

编辑:

每当我运行命令时,它就会告诉我

  

“ DisplayName”未被识别为内部或外部命令,可操作程序或批处理文件。

1 个答案:

答案 0 :(得分:2)

如果那么简单的话........

String command = "powershell.exe Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | DisplayName, DisplayVersion, InstallDate | ConvertTo-Json";
Process powerShellProcess = Runtime.getRuntime().exec(command);

我不知道您在哪里找到了那段代码,但是不幸的是,由于您已经发现了那段代码,所以它并没有那么有效。您收到错误的原因:

'DisplayName' is not recognized as an internal or external command, operable program or batch file.

是因为您要运行的PowerShell命令字符串需要按照执行方式应用于 PowerShell命令提示符,而不是 Windows命令提示符。为此,您需要启动PowerShell,首先键入 PowerShell ,然后按Enter键。该窗口看起来是一样的,但是当您在使用PowerShell提示符时,提示符和闪烁的插入号之间会有空格,并且在命令提示符窗口标题栏中显示了PowerShell,您将始终知道,{{1} }。要退出PowerShell提示符,只需键入 exit ,然后按Enter键。现在注意到标题栏了吗?

但是,还有另一种方法,那就是使用PowerShell的 -Command 命令并将命令字符串括在引号中,但是在我们开始之前,您需要知道命令字符串有轻微缺陷。 ..您缺少一个特定的参数,即 Select-Object 参数,而该参数恰好在 DisplayName 属性名称之前:

Command Prompt - PowerShell

毕竟,您要选择特定的对象时,才需要使用此参数来使特定的命令字符串起作用。

PowerShell帮助指定 -Command 命令:

  

执行指定的命令(和任何参数),就像它们一样   在PowerShell命令提示符下键入,然后退出,除非   指定了 NoExit 。 Command的值可以是“-”,字符串或脚本块。

     

如果Command的值为“-”,则从标准中读取命令文本   输入。

     

如果Command的值是一个脚本块,则该脚本块必须为   用大括号({})括起来。您只能在以下情况下指定脚本块   在Windows PowerShell中运行PowerShell.exe。结果   脚本块作为反序列化的XML返回到父外壳   对象,而不是活动对象。

     

如果Command的值为字符串,则Command必须为最后一个   该命令中的参数,因为在   命令被解释为命令参数。

     

要编写运行Windows PowerShell命令的字符串,请使用   格式:“&{}”,其中引号表示字符串   然后调用操作符(&)使命令执行。

好吧,这显然给了这个问题一些启示。因此,有两种方法可以完成此操作,将命令字符串括在引号中,或将命令字符串设置为被调用的命令字符串块:

用引号引起来:

          Here
      ┌─────┴─────┐
... | Select-Object DisplayName, DisplayVersion, InstallDate | ConvertTo-Json

在PowerShell调用命令字符串块中:

String command = "PowerShell.exe -Command \"Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion, InstallDate | ConvertTo-Json\"";
Process powerShellProcess = Runtime.getRuntime().exec(command);

嗯...现在就这么简单。

下面是一种可以帮助您消除麻烦的方法。它会自动调用PowerShell,因此您所需要提供的只是命令字符串,其中没有“ powershell.exe”。

String command = "PowerShell.exe -Command \"& {Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion, InstallDate | ConvertTo-Json}\"";
Process powerShellProcess = Runtime.getRuntime().exec(command);

以下是如何与特定的命令字符串一起使用的方法:

/**
 * Most PowerShell commands need to be run through a PowerShell Command
 * Window (unless the -Command is used) which means that PowerShell needs 
 * to be run first before the command can be used otherwise you end up 
 * receiving an error something like:<pre>
 *
 *    'CommandName' is not recognized as an internal or external command,
 *    operable program or batch file.</pre><br>
 * <p>
 * This method solves that problem. Here you don't supply the "PowerShell"
 * substring as the start of your Command String but instead you merely supply
 * the Command String you would supply to PowerShell. As an example, suppose
 * you want to collect the list of files and folders contained within the
 * currently focused drive and directory within the local file system:
 * <pre>
 *      {@code
 *          String command = "ls";   // A PowerShell command
 *          List<String> list = runPowerShellCommand(command);
 *
 *          for (int i = 0; i < list.size(); i++) {
 *              System.out.println(list.get(i));
 *          }
 *      }</pre>
 * <p>
 * Your console window will display a list of files and folders.<br><br>
 *
 * @param commandString (String) The command string to run through
 *                      PowerShell.<br>
 *
 * @param options       (Optional - Two Of, Boolean):<pre>
 *      trimLines       - (Boolean - Default is true) By default lines returned
 *                        from the PowerShell process are added to a List Interface
 *                        object with all lines trimmed. If you don't want this
 *                        then supply false to this optional parameter. If you are
 *                        retrieving data from PowerShell in a specific format like
 *                        Json then you definitely want to pass boolean false to
 *                        this parameter.
 *
 *                        If an argument is passed to the optional skipBlankLines
 *                        parameter then you MUST pass an argument to this optional
 *                        parameter as well.
 *
 *      skipBlankLines  - (Boolean - Default is true) By default blank lines returned
 *                        from the PowerShell process are skipped and not added to the
 *                        List Interface object that will be returned. If you don't want
 *                        this then supply false to this optional parameter. If you are
 *                        retrieving data from PowerShell in a specific format like
 *                        Json then you definitely want to pass boolean false to
 *                        this parameter.
 *
 *                        If an argument is passed to this optional parameter then
 *                        you MUST pass an argument to the trimLines optional parameter
 *                        as well.</pre>
 *
 * @return (List Interface of String ({@code List<String>})) PowerShell
 *         output data.<br>
 *
 * @throws java.io.IOException
 */
public List<String> runPowerShellCommand(String commandString, boolean... options) throws IOException {
    List<String> list = new ArrayList<>();
    boolean trimLines = true;       // Default
    boolean skipBlankLines = true;  // Default
    // Setup optional parameters if supplied.
    if (options.length > 0) {
      trimLines = options[0];
      if (options.length >= 2) {
         skipBlankLines = options[1];
      }

    }

    // Fire up PowerShell and run the supplied command string through it.
    Runtime runtime = Runtime.getRuntime();
    String cmds[] = {"powershell", commandString};
    Process proc = runtime.exec(cmds);
    // Try With resources used here.
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
        String line;
        while ((line = reader.readLine()) != null) {
            if (trimLines) {
                line = line.trim();
            }
            if (skipBlankLines) {
                if (line.trim().equals("")) {
                    continue;
                }
            }
            list.add(line); // Add line from input stream to list.
        }
    }
    proc.destroy(); // Kill the process
    return list;    // return the goods if any
} 

这将在控制台窗口中显示您的注册表数据查询。

请注意,Windows注册表中实际上有三个位置可以容纳专门安装的应用程序,您可以考虑对所有应用程序进行极化,而忽略重复项:

  • 用户在程序和部分中看到的程序列表 控制面板的功能基于内容 注册表项:

    HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall

    上面的注册表项仅包含所有已安装”的程序 用户”

  • 对于64位操作系统上的32位应用程序,您将 需要另外获取注册表分支的内容:

    HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall

  • 如果以“为此用户” 模式安装了应用程序,则 它应该出现在注册表项中:

    HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Uninstall

因此,要获取已安装软件的完整列表,您将需要检查Windows注册表的所有三个分支的信息。