Как выгрузить запущенную программу

Подскажите, пожалуйста, каким образом можно выгрузить с# библиотеку из нативного кода или как-то изнутри самой библиотеки. Дело в том, что есть нативное оконное приложение на delphi. Для него мной был написан плагин на с# с вызовом функции, внутри которой стартует отдельный поток с wpf приложением и запуском окна, но внутри основного процесса.

В приложении на delphi dll подключается с помощью WinAPI (LoadLibrary, GetProcAddress и FreeLibrary). Так вот, при освобождении с помощью FreeLibrary плагин на самом деле не освобождается, а продолжает висеть в CLR вплоть до завершения процесса. В англоязычном сегменте, нашёл ответ, что нужно выгружать AppDomain, но без примеров. Как в моём случае решить данную проблему, откуда выгружать AppDomain, каким образом? Экспортируемая функция внутри C# либы выглядит следующим образом:

public static int showCyclegramm(IntPtr allWindowsClosedCallback) < if (_wpfLoaded) App.ShowWindow(); else < _thread = new Thread(App.StartWpf); _thread.SetApartmentState(ApartmentState.STA); _thread.Start(allWindowsClosedCallback); _wpfLoaded = true; >return 0; >

StartWpf это по сути тот же main из обычного WPF приложения:

Как добавить, удалить программы из автозапуска Windows 10, 8 или 7


public static void StartWpf(object allWindowsClosedCallback) < var cPointer = (IntPtr) allWindowsClosedCallback; if (cPointer != IntPtr.Zero) _allClosedWindowsAction = Marshal.GetDelegateForFunctionPointer((IntPtr) allWindowsClosedCallback); try < _app = new App(); >catch (InvalidOperationException e) < MessageBox.Show(«Последнее окно было закрыто. Перезагрузите библиотеку»); return; >_app.InitializeComponent(); _app.Run(); >

Отслеживать

задан 4 апр 2019 в 7:09

63 7 7 бронзовых знаков

Почитай про плагинную систему, там хороший пример как загружать выгружать различные dll. Как правило предлагается создавать сабдомены для запуска сторонних dll, а потом просто убиваешь (выгружаешь) этот сабдомен и все.

Источник: ru.stackoverflow.com

Как сохранить список запущенных процессов в Windows

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

К счастью, есть и другие простые способы сохранить список запущенных процессов в Windows. Проверять Как использовать диспетчер задач Windows.

Как сохранить список запущенных процессов в Windows - Windows

Как быстро установить все нужные программы на компьютер

Зачем мне список запущенных процессов?

Основной причиной экспорта списка процессов на вашем компьютере является устранение неполадок. Вы можете просматривать процессы в режиме реального времени с помощью диспетчера задач, но вам может потребоваться предоставить список процессов третьей стороне. В этом случае у вас должна быть возможность сохранить информацию в удобном для чтения формате.

Также может быть полезно иметь историю процессов, запущенных в определенное время, чтобы сравнить их с теми, которые выполнялись в более позднюю дату. Например, если приложение замедляет работу вашего компьютера. Наличие сохраненного списка позволяет сравнить процессы, которые выполнялись до и после установки приложения.

Читайте также:
Парус как работать в программе

Как экспортировать список процессов с помощью командной строки

Вы можете ввести простую команду в командной строке, чтобы экспортировать текстовый список каждого процесса, запущенного на вашем компьютере. Вот как это сделать.

  • Откройте инструмент командной строки, введя «cmd» в поиске Windows и нажав Enter.
  • Теперь вы можете использовать команду списка задач, чтобы экспортировать список в новый файл .txt.
  • Например, вы можете написать следующее:

tasklist /v > “%userprofile%DesktopRunning-Process-List.txt”

Как сохранить список запущенных процессов в Windows - Windows

  • На рабочем столе появится новый текстовый документ Running-Process-List.txt, содержащий полный список запущенных процессов. Список также будет содержать такие сведения, как идентификатор процесса, использование памяти и т. д.

Раздел %Профиль пользователя% команды является переменной окружения. Он работает как ярлык и представляет собой более простой способ ввести путь к папке в командной строке и других инструментах Windows. Заменяет часть C:Users[Имя пользователя] пути к папке.

Вы можете применять к команде разные параметры для вывода списка в разных форматах. Например, в приведенной выше команде параметр . вызывает /v В выводе списка в подробном формате. Если оставить так, список будет отформатирован в усеченном виде.

Как сохранить список запущенных процессов в Windows - Windows

Как экспортировать список процессов с помощью PowerShell

При желании вы можете использовать PowerShell для сохранения списка запущенных процессов вместо использования командной строки. Список, созданный при использовании PowerShell, также можно изменить с помощью параметров.

  • Откройте PowerShell, введя «power» в поиске Windows и выбрав его из списка результатов.
  • Вам не нужно использовать «Запуск от имени администратора» при открытии PowerShell, но если у вас возникли проблемы с созданием меню, вам может помочь «Запуск от имени администратора».
  • В PowerShell вам нужно использовать следующую команду:

Get-Process | Out-File -filepath “$Env:userprofileDesktopRunning-Process-List.txt”

Как сохранить список запущенных процессов в Windows - Windows

  • Документ Running-Process-List.txt должен быть сохранен на рабочем столе.

Вы можете прочитать больше о Использование PowerShell и командной строки В нашем руководстве о том, что отличает их.

Что такое идентификатор процесса?

Каждому процессу присвоен уникальный идентификационный номер. Это называется идентификатором процесса, PI или PID. Идентификаторы процессов используются всеми основными операционными системами, включая Linux, macOS, Unix и, конечно же, Windows. PID — важная часть Windows, и система может использовать его, помимо прочего, для идентификации процесса отладки.

Как сохранить список запущенных процессов в Windows - Windows

Знание PID приложения помогает идентифицировать приложения, которые работают в нескольких экземплярах, например, при редактировании двух разных файлов в одном и том же приложении. Как показано выше, идентификатор процесса можно использовать для фильтрации процессов, отображаемых в выходном списке запущенных процессов.

Помимо методов, описанных здесь, есть еще несколько способов найти Идентификаторы процессов Windows.

Упростите сохранение списков процессов Windows

Диспетчер задач — полезный инструмент, но он не дает вам возможности просматривать процессы ни в каком другом режиме, кроме реального времени. Создание и экспорт списка запущенных процессов Windows может быть очень полезным для устранения неполадок с приложениями и системными инструментами, и теперь вы точно знаете, как это сделать. Теперь вы можете просмотреть Лучшие альтернативы диспетчеру задач для Windows 10.

Читайте также:
Известны результаты выполнения производственной программы виды продукции

Источник: www.dz-techs.com

Как выгрузить dll из Java-машины

Java взаимодействует с операционной системой через методы, помеченные ключевым словом native, при помощи системных библиотек, загружаемых процедурой System.loadLibrary().

Загрузить системную библиотеку очень просто, а вот чтобы ее выгрузить, как оказалось, нужно приложить немало усилий. Как именно выгружаются системные библиотеки, и зачем это нужно я постараюсь рассказать.

Предположим, мы хотим сделать небольшую утилиту, которую будут запускать пользователи на своих компьютерах в локальной сети. Нам бы хотелось избавить пользователей от проблем с установкой и настройкой программы, но нет ресурсов на развертывание и поддержку централизованной инфраструктуры. В таких случаях обычно собирают программу вместе со всеми зависимостями в единый jar-файл. Это легко сделать при помощи maven-assembly-plugin или просто экспортировать из IDE Runnable jar. Запуск программы будет осуществляться командой:

java -jar my-program.jar

К сожалению, это не работает, если одна из библиотек требует для своей работы системную динамическую библиотеку, проще говоря dll. Обычно в одном из классов такой библиотеки в статическом инициализаторе делается вызов System.loadLibrary(). Чтобы dll загрузилась, нужно положить ее в каталог, доступный через системное свойство JVM java.library.path. Как это ограничение можно обойти?

Запакуем dll внутрь jar-файла. Перед началом использования классов, требующих подгрузки dll, создадим временный каталог, извлечем библиотеку туда и добавим каталог в java.library.path. Выглядеть это будет примерно так:

prepareLibrary

private void addLibraryPath(String pathToAdd) throws ReflectiveOperationException < Field usrPathsField = ClassLoader.class.getDeclaredField(«usr_paths»); usrPathsField.setAccessible(true); String[] paths = (String[]) usrPathsField.get(null); String[] newPaths = Arrays.copyOf(paths, paths.length + 1); newPaths[newPaths.length — 1] = pathToAdd; usrPathsField.set(null, newPaths); >private Path prepareLibrary() throws IOException, ReflectiveOperationException < Path dir = Files.createTempDirectory(«lib»); try (InputStream input = ExampleClass.class.getResourceAsStream(«custom.dll»)) < if (input == null) < throw new FileNotFoundException(«Can’t load resource custom.dll»); >Files.copy(input, dir.resolve(«custom.dll»)); > addLibraryPath(dir.toAbsolutePath().toString()); return dir; >

К сожалению, приходится химичить с reflection, потому что стандартных методов расширить java.library.path Java не предоставляет.

Теперь загрузка библиотеки проходит для пользователя прозрачно, и он не должен беспокоиться о копировании файлов или настройке переменных окружения. Для работы по-прежнему достаточно просто запустить обычный скрипт. Однако после каждого запуска программы остается временный каталог с файлами. Это не очень хорошо, поэтому на выходе надо выполнить очистку.

try < . >finally

Но на Windows это не работает. Загруженная в JVM библиотека блокирует dll-файл и каталог, в котором он лежит. Таким образом, чтобы решить задачу аккуратного завершения программы, надо выгрузить из JVM системную динамическую библиотеку.

Попытка решения

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

Читайте также:
Знаете ли вы программа

if (!delete(dir))

Как быстрое, но не самое красивое решение, я использовал планировщик. На выходе создаю xml-файл с заданием на выполнение через 1 минуту команды «cmd /c rd /s /q temp-dir» и загружаю задание в планировщик командой «schtasks -create taskName -xml taskFile.xml». К моменту выполнения задания программа уже завершена, и файлы никто не держит.

Самое же верное решение — это обеспечить выгрузку библиотеки средствами Java-машины. Документация говорит о том, что системная библиотека будет выгружена при удалении класса, а класс удаляется сборщиком мусора вместе с класслоадером, когда не осталось ни одного экземпляра из его классов. На мой взгляд, лучше всегда писать такой код, который полностью очищает после себя всю память и другие ресурсы. Потому что если код делает что-то полезное, рано или поздно захочется его переиспользовать и задеплоить на какой-нибудь сервер, где установлены и другие компоненты. Поэтому я решил потратить время на то, чтобы разобраться, как корректно программно выгрузить dll.

Использование класслоадера

В моей программе проблемы исходили из JDBC-драйвера, поэтому дальше я буду рассматривать пример с JDBC. Но и с другими библиотеками можно работать аналогичным образом.

Если dll загружена из системного загрузчика классов, то выгрузить ее уже не получится, поэтому необходимо создать свой класслоадер таким образом, чтобы класс, подтягивающий библиотеку, был загружен из него. Новый класслоадер должен быть связан с системным класслоадером через свойство parent, иначе в нем не будут доступны классы String, Object и другие необходимые в хозяйстве в вещи.

Загрузка класса из нового загрузчика (1)

ClassLoader parentCl = ExampleClass.class.getClassLoader(); classLoader = new URLClassLoader(new URL[0], parentCl); Class.forName(«org.jdbc.CustomDriver», classLoader, true); try (Connection connection = DriverManager.getConnection(dbUrl, dbProperties)) < if (connection.getClass().getClassLoader() != classLoader) < System.out.printf(«Что-то пошло не так%n»); >. >

Не работает. При загрузке класса сначала производится попытка поднять его из родительского загрузчика, поэтому наш драйвер загрузился не так, как нам нужно. Для использования нового класслоадера, нужно JDBC-драйвер из jar-файла программы удалить, чтобы он не был доступен системному загрузчику. Значит, запаковываем библиотеку в виде вложенного jar-файла, а перед использованием разворачиваем его во временном каталоге (в том же, где и dll у нас лежит).

Загрузука класса из нового загрузчика (2)

ClassLoader cl = ExampleClass.class.getClassLoader(); URL url = UnloadableDriver.class.getResource(«CustomJDBCDriver.jar»); if (url == null) < throw new FileNotFoundException(«Can’t load resource CustomJDBCDriver.jar»); >Path dir = prepareLibrary(); try (InputStream stream = url.openStream()) < Path target = dir.resolve(«CustromJDBCDriver.jar»); Files.copy(stream, target); url = target.toUri().toURL(); >ClassLoader classLoader = new URLClassLoader(new URL[] , cl); Class.forName(«org.jdbc.CustomDriver», true, classLoader); try (Connection connection = DriverManager.getConnection(dbUrl, dbProperties)) < if (connection.getClass().getClassLoader() != classLoader) < System.out.printf(«Что-то пошло не так%n»); >else < System.out.printf(«Получилось, можно идти дальше%n»); >. >

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru