Получить все установленные на данный момент программы на Windows 7,8 и 10 - PullRequest
0 голосов
/ 29 января 2019

Мне в основном нужно получить name, version и install_date из всего программного обеспечения, установленного в Windows (7,8,10).

Я нашел это:

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 голосов
/ 29 января 2019

Если бы это было так просто ........

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 , а затем нажав клавишу ВВОД.Окно выглядит одинаково, но вы всегда будете знать, когда работаете с приглашением PowerShell, когда между приглашением и мигающим символом вставляется пробел, и, конечно, PowerShell указывается в строке заголовка окна командной строки: Command Prompt - PowerShell.Чтобы выйти из командной строки PowerShell, просто введите exit и нажмите клавишу ВВОД.Заметьте строку заголовка сейчас?

Однако существует и другой способ: использовать команду -Command PowerShell и заключить вашу командную строку в кавычки, но прежде чем мы начнем, вам нужно знать, что ваша командная строка немногоошибка ... у вас отсутствует конкретный аргумент, аргумент Select-Object , и он будет указан непосредственно перед именем свойства DisplayName :

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

Youэтот аргумент нужен для работы вашей конкретной командной строки, в конце концов, вы выбираете определенные объекты.

Справка PowerShell указывает, что команда -Command :

выполняет указанные команды (и любые параметры), как если бы они были введены в командной строке PowerShell, и затем завершается, если не указано NoExit .Значением Command может быть «-», строка или блок скрипта.

Если значение Command равно "-", текст команды читается из стандартного ввода.

Если значение Command является блоком сценария, блок сценария должен быть заключен в фигурные скобки ({}).Вы можете указать блок скрипта только при запуске PowerShell.exe в Windows PowerShell.Результаты блока скрипта возвращаются в родительскую оболочку в виде десериализованных объектов XML, а не живых объектов.

Если значение Command является строкой, команда должна быть последним параметром в команде, поскольку любые символы вводятсяпосле интерпретации команды в качестве аргументов команды.

Чтобы написать строку, запускающую команду Windows PowerShell, используйте формат: «& {}», где кавычки указывают строку и оператор invoke (&)вызывает выполнение команды.

Ну, это, очевидно, немного освещает предмет.Таким образом, есть два способа сделать это: заключить командную строку в кавычки или сделать командную строку вызванным блоком командной строки:

в кавычках:

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 Invoke:

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».

<code>/**
 * 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.

*

* Этот метод решает эту проблему.Здесь вы не предоставляете подстроку «PowerShell» * в качестве начала вашей командной строки, а вместо этого просто указываете * командную строку, которую вы бы поставили для PowerShell.В качестве примера, предположим, * что вы хотите собрать список файлов и папок, содержащихся в * текущем фокусированном диске и каталоге в локальной файловой системе: *

 *      {@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));
 *          }
 *      }
*

* В вашем окне консоли отобразится список файлов иfolder.

* * @param commandString (String) Командная строка для запуска через * PowerShell.
* * @param options (Необязательно - Two Of, Boolean):

 *      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.
* * @return (Список интерфейса строки ({@code List })) PowerShell * выходные данные.
** @throws java.io.IOException * / public List runPowerShellCommand (String commandString, boolean ... options) throws IOException {List list = new ArrayList <> ();логическое значение trimLines = true;// логическое значение по умолчанию skipBlankLines = true;// По умолчанию // Настройка необязательных параметров, если они есть.if (options.length> 0) {trimLines = options [0];if (options.length> = 2) {skipBlankLines = options [1];}} // Запускаем PowerShell и запускаем через него предоставленную командную строку.Runtime runtime = Runtime.getRuntime ();String cmds [] = {"powershell", commandString};Процесс proc = runtime.exec (cmds);// Попробуйте с ресурсами, используемыми здесь.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 (строка);// Добавить строку из входного потока в список.}} proc.destroy ();// убить процесс return list;// вернуть товар, если есть}

И вот как вы можете использовать его с вашей конкретной Командной Строкой:

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

List<String> list;
try {
    list = runPowerShellCommand(command, false, false);
    // Display the list in console...
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }
}
catch (IOException ex) {
    System.err.println(ex.getMessage());
}

Это отобразит ваш запрос данных реестра в КонсолиWindow.

В качестве дополнительного примечания, в реестре Windows есть три места, в которых могут храниться специально установленные приложения, и вы можете рассмотреть возможность их опроса и игнорировать дубликаты:

  • Список программ, которые пользователь видит в разделе Программы и компоненты Панели управления, построен на основе содержимого раздела реестра:

    HKEY_LOCAL_MACHINE \ SOFTWARE\ Microsoft \ Windows \ CurrentVersion \ Uninstall

    Приведенный выше раздел реестра содержит только программы, установленные «для всех пользователей» Windows.

  • Для 32-разрядных приложений в 64-разрядной операционной системе вам необходимо дополнительно получить содержимое ветви реестра:

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

  • Если приложение было установлено в режиме «для этого пользователя» , то оно должно присутствовать враздел реестра:

    HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Uninstall

Соответственно, чтобы получить complete список установленного программного обеспечения, вам нужно будет получить информацию из всех трех ветвей реестра Windows.

...