Dale 2012 Ответов: 1

Введите несколько команд только для одного экземпляра процесса


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

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


Это может быть легко сделать, как я уверен, но я не могу найти много помощи из-за природы этого, где люди только хотят сделать что-то, например, начать". notepad.exe". Мой пример должен сначала запустить процесс, а затем ему передаются аргументы для этого файла, который является путем к файлу процесса, который я хочу запустить, и путем к файлу файла, который я хочу выполнить работу.

(например.) "C:\folder\process.exe" C:\folder\Myfile.txt"



Заранее спасибо..






Вот код, который я нашел...



Окно клиента (приложение Windows form)
состоит из одного текстового поля с именем txtText и одной кнопки с именем cmdSend
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Ipc
Public Class Form1

    Private Sub cmdSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSend.Click
        Dim ipcCh As New IpcChannel("cmd.exe")
        ChannelServices.RegisterChannel(ipcCh, False)

        Dim obj As SharedInterfaces.ICommunicationService = _
          DirectCast(Activator.GetObject(GetType(SharedInterfaces.ICommunicationService), _
          "ipc://IPChannelName/SreeniRemoteObj"), SharedInterfaces.ICommunicationService)
        obj.SaySomething(txtText.Text)

        ChannelServices.UnregisterChannel(ipcCh)
    End Sub
End Class



Консоль сервера (консольное приложение)
Вот код из Main.vb
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Ipc
 
Module Main
    Sub Main()
        Dim ipcCh As IpcChannel
        ipcCh = New IpcChannel("IPChannelName")

        ChannelServices.RegisterChannel(ipcCh, False)
        RemotingConfiguration.RegisterWellKnownServiceType( _
             GetType(CommunicationService), "SreeniRemoteObj", _
                           WellKnownObjectMode.Singleton)

        Console.WriteLine("Press ENTER to quit")
        Console.ReadLine()
    End Sub
End Module


Также в консольной программе есть еще одна под названием CommunicationService.vb
Public Class CommunicationService
    Inherits MarshalByRefObject
    Implements SharedInterfaces.ICommunicationService
    Public Sub SaySomething(ByVal text As String) Implements SharedInterfaces.ICommunicationService.SaySomething
        Console.WriteLine("The client said : " & text)
    End Sub
End Class


И, наконец, библиотеку классов, часть называется SharedInterfaces

Public Interface ICommunicationService
    Sub SaySomething(ByVal text As String)
End Interface




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

спасибо Вам за ваших пациентов.

1 Ответов

Рейтинг:
12

Sergey Alexandrovich Kryukov

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

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

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

Броско, не правда ли?

[РЕДАКТИРОВАТЬ]

Для синтаксического анализа командной строки я бы предложил свою статью CodeProject: Утилита командной строки на основе перечисления[^].

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

—СА


Dale 2012

Это очень интересно, вы говорите, что я могу отправить путь к файлу и аргументы на канал IPC?..

Sergey Alexandrovich Kryukov

Да, конечно. Я почти все объяснил. Это не крошечный код. Просто изучите дистанционное управление, оно очень бережливое. Альтернативой является WCF (self-hosted), который имеет такие же каналы. Я не использовал WCF для этой цели, потому что старый remoting просто достаточно хорош, и я знаю случаи, когда remoting был более гибким и давал мне дополнительные возможности, но для этого случая, и, если случайно у вас есть опыт работы с WCF, это должно быть альтернативой.

Один маленький секрет. Вам нужен какой-то строковый констант, чтобы назвать канал уникальным. Я использовал систему.Отражение.Собрание.GetEntryAssembly().Расположение для этого имени (возможно, мне пришлось заменить разделитель путей, я просто сейчас не помню). Поскольку ни одно другое приложение не может иметь такого же местоположения, это уникальное для системы имя. Конечно, если вы скопируете приложение в другое место, оно не будет работать как отдельный экземпляр, но это нормально — в конце концов, какова идентичность приложения. Кроме того, вы можете подписать сборку и использовать строгое имя или маркер открытого ключа для имени канала. Это просто тонкость...

—СА

Dale 2012

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


спасибо я постараюсь

Sergey Alexandrovich Kryukov

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

Dale 2012

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

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

Sergey Alexandrovich Kryukov

Я ничего не знаю о таком коде... Я предлагаю вам использовать мой метод; он хорошо определен и прост...
—СА

Dale 2012

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

Sergey Alexandrovich Kryukov

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

Dale 2012

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

В окне клиента что это такое?... "ipc://IPChannelName/SreeniRemoteObj" могу ли я указать здесь что-то другое, например имя моего процесса, в котором я хочу запустить строку, которую я отправляю?.

В окне формы клиент снова появляется.. Dim ipcCh как новый IpcChannel("cmd.exe")
это, конечно, не открывает CMD, но относится к чему?...

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

Sergey Alexandrovich Kryukov

Да, в основном. Он обязательно должен быть в форме
string.Format("ipc://{0}/{1}", ChannelName, ProxiObjectName);

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

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

Единственная цель этого ipc:// path состоит в том, чтобы избежать ситуации, когда какое-то другое приложение использует то же имя канала, или, с тем же каналом, это или другое приложение использует то же значение для ProxiObjectName. Это требование уникальности.

—СА

Dale 2012

кроме того, можно ли использовать этот пример непосредственно с процессом, а не с консольным окном?

Sergey Alexandrovich Kryukov

Конечно, его можно использовать где угодно? Я упоминал какой-либо пользовательский интерфейс или тип приложения? Механизм находится в каждом приложении. (Не применимо к приложениям, не размещенным "нормально": служба Windows, ASP.NET приложение, любые виды апплетов.) Просто посмотрите на сценарий, который я описал, и вы увидите, что тип приложения, пользовательский интерфейс, консоль или только консоль-все это несущественные детали.

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

—СА

Dale 2012

есть идеи?...

Dale 2012

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

Sergey Alexandrovich Kryukov

Читайте о дистанционном управлении, и это объяснит вам, что такое канал. Нет, канал-это вообще не название. Это абстракция транспорта. Другими словами, вы можете использовать один и тот же код, но в конечном итоге изменить канал с IPC на TCP, адресовать разные службы, не меняя другие части кодов...

Сбивает с толку? Что вы можете сделать... вам нужно немного ознакомиться с технологией, это вас не смутит. Это другого пути нет...
—СА

Dale 2012

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

Dale 2012

можете ли вы объяснить, как это сделать с помощью какого-либо процесса или .EXE-файл?

Sergey Alexandrovich Kryukov

Я хотя и объясняю это в ответе после "вот такой сценарий". Какая его часть нуждается в более подробном объяснении?
В принципе, вы добавляете к самому началу вашего основного что-то вроде
если (FirstInstanceDetected(командную строку)) выход;
И этот метод предиката возвращает true, если соединение успешно и отправляет параметры, создает удаленный объект в противном случае и возвращает false.
—СА

Dale 2012

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

Sergey Alexandrovich Kryukov

Это странно. Если вы разместили какой-то код, вы должны объяснить, что он делает... Я этого не писал...
—СА

Dale 2012

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

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

Sergey Alexandrovich Kryukov

Нет, это не хорошо, что вы создаете канал по щелчку мыши. Просто подумайте о логике. Я действительно описал этот порядок в своем комментарии выше. Ты только посмотри...
—СА

Dale 2012

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