Как найти информацию о 64-разрядном процессе с помощью 32-разрядного процесса

#vb.net

#vb.net

Вопрос:

У меня есть 32-разрядное приложение, которое запускает второе приложение, которое может быть 32 или 64-разрядным в зависимости от компьютера, на котором оно запущено.

Я хочу, чтобы одновременно запускался только один экземпляр второго приложения, и мне нужно, чтобы первое приложение не запускалось более одного раза.

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

Есть ли у кого-нибудь предложения по идентификации 64-разрядных процессов и их исходной папки из 32-разрядного приложения?

Спасибо, SH

Ответ №1:

Для этого вы можете использовать WMI API ( System.Management пространство имен), в частности, ManagementObjectSearcher. В приведенном ниже примере показано, как получить идентификатор процесса и полную командную строку из всех запущенных экземпляров notepad.

 Imports System.Management

Module Module1

    Sub Main()

        Dim wmi = New ManagementObjectSearcher("SELECT ProcessId, CommandLine FROM Win32_Process WHERE CommandLine LIKE ""%notepad%""")
        Dim result = wmi.Get().OfType(Of ManagementObject)()
        For Each r In result
            Console.WriteLine("Process ID: {0}, Command Line: {1}" r("ProcessId"), r("CommandLine"))
        Next
    End Sub

End Module
  

Комментарии:

1. Вы уверены, что приведенный выше код при запуске как часть 32-разрядного процесса может получать информацию из 64-разрядного процесса? Я попытался ввести ваш код, но получил синтаксические ошибки. Я совершенно не знаком с WMI API.

Ответ №2:

Я думаю, было бы проще, если бы вы установили мьютекс при запуске второго приложения.
В главном приложении вы могли бы сделать это: если Мьютекс не существует, вы запускаете второе приложение (которое создает Мьютекс при запуске и освобождает его при закрытии), в противном случае вы пропускаете…

ОТРЕДАКТИРОВАНО: Вы не можете отредактировать второе приложение, чтобы вставить создание мьютекса, ок.
Но вы можете сделать это в главном приложении:

  • Создайте фонового рабочего BackgroudWorker wrk
  • Установите для частного bool значение true: bool running = false
  • Запустите wrk, когда вы хотите запустить новое приложение: if (running) return; running = true;
  • wrk создает процесс и ожидает его завершения
  • когда wrk заканчивается running = false

Просто идея…

ОТРЕДАКТИРОВАНО СНОВА:
Если вы закроете первое приложение и снова откроете его, пользователь сможет снова запустить второе приложение.
Итак, вы могли бы сделать это:

  • Создайте фонового рабочего BackgroudWorker wrk
  • Напишите файл tmp (в NTFS он может быть пустым)
  • Запустите wrk, когда вы хотите запустить новое приложение:
    если ваш файл tmp существует, выйдите;
  • wrk создает процесс и ожидает его завершения
  • по завершении wrk удаляется файл tmp

С помощью этого метода, даже если пользователь завершает работу с вашим первым приложением, файл tmp остается на жестком диске; поэтому, когда пользователь снова запускает первое приложение, второе приложение выполняться не будет.
Помните, что если пользователь достаточно умен, чтобы это не обнаруживать, он может вручную удалить файл, и дело сделано.
Наконец: вы уверены, что пользователь не может напрямую запустить второе приложение?

Комментарии:

1. Я делал это в других приложениях. У меня нет возможности редактировать второе приложение. Первое приложение должно идентифицировать процессы и определить, какие (если таковые имеются) из них были запущены из определенной папки.

2. Я думаю, что мое решение более безопасно, чем проверка процессов, потому что для этого вы должны быть администратором (и какой-то процесс может быть скрыт)

3. У меня вопрос о вашей идее BackgroundWorker. Будет ли это работать между сеансами первого приложения? В настоящее время наше программное обеспечение использует таймеры и события таймера, чтобы отключить возможность запуска второго приложения из сеанса. Наша проблема возникает, когда пользователи запускают второе приложение, затем закрывают и повторно открывают первое приложение. После закрытия и повторного открытия у него нет «знаний» о том, что было запущено второе приложение, поэтому мы проверяем это. Спасибо за вашу помощь, если эта идея backgroundworker будет охватывать сеансы, вероятно, это то, что мы ищем.

4. @Superhuman: Я думаю, что проблема для нескольких сеансов все еще присутствует. если вы закроете первое приложение, при повторном открытии у него будет значение running = false, так что способа нет. Посмотрите на мой отредактированный пост для лучшего решения

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