как я могу запустить другое приложение на панели моей программы на c #?

<p>я много читал о том, как запустить приложение из программы на c # (process.start ()), но я не смог найти никакой информации о том, как запустить это новое приложение на панели моей программы на c # , например, я бы хотел, чтобы щелчок кнопки открывал notepad.exe в моем приложении, а не внешне.</p>

<p>я не знаю, рекомендуется ли это использовать, но инфраструктура "связывание и внедрение объектов" позволяет вам встраивать определенные объекты/элементы управления непосредственно в ваше приложение. это, вероятно, будет работать только для определенных приложений, я не уверен, является ли блокнот одним из них. для действительно простых вещей, таких как блокнот, вам, вероятно, будет легче работать с элементами управления текстового поля, предоставляемыми любым используемым средством (например, winforms).</p><p>вот ссылка на ole информацию, чтобы начать:</p><p> <a href="http://en.wikipedia.org/wiki/object\_linking\_and\_embedding">http://en.wikipedia.org/wiki/object\_linking\_and\_embedding</a> </p>

<p>используя win32 api, можно "съесть" другое приложение. по сути, вы получаете верхнее окно для этого приложения и задаете его родительский дескриптор панели, в которую хотите поместить его. если вам не нужен эффект стиля mdi, вам также нужно настроить окно стиль, чтобы сделать его максимально развернутым и удалить строку заголовка.</p><p>вот простой пример кода, где у меня есть форма с кнопкой и панелью:</p><pre><code>using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.linq; using system.text; using system.windows.forms; using system.diagnostics; using system.runtime.interopservices; using system.threading; namespace windowsformsapplication2 { public partial class form1 : form { public form1() { initializecomponent(); } private void button1\_click(object sender, eventargs e) { process p = process.start("notepad.exe"); thread.sleep(500); // allow the process to open it's window setparent(p.mainwindowhandle, panel1.handle); } [dllimport("user32.dll")] static extern intptr setparent(intptr hwndchild, intptr hwndnewparent); } } </code></pre><hr><p>я только что видел другой пример, где они вызывали waitforinputidle вместо сна. таким образом, код будет выглядеть так:</p><pre><code>process p = process.start("notepad.exe"); p.waitforinputidle(); setparent(p.mainwindowhandle, panel1.handle); </code></pre><p>в code project есть хорошая статья, посвященная всему процессу: <a href="http://www.codeproject.com/kb/miscctrl/appcontrol.aspx">размещение exe-приложений в проекте winform</a> </p>

<ul> <li>добавление решения в ответ. **</li> </ul><p>этот код помог мне закрепить исполняемый файл в форме windows. например notepad, excel, word, acrobat reader и многие другие ...</p><p>но это не будет работать для некоторых приложений. как иногда, когда вы запускаете процесс какого-то приложения .... ждите простоя ... и попробуйте получить его mainwindowhandle .... до тех пор, пока дескриптор главного окна не станет нулевым .....</p><p>поэтому я сделал один трюк, чтобы решить это</p><p>если вы получаете дескриптор главного окна как ноль ..., тогда ищите все запущенные процессы в sytem и находите ваш процесс ... тогда получите главный хэдл процесса и панель set в качестве его родителя.</p><pre><code> processstartinfo info = new processstartinfo(); info.filename = "xxxxxxxxxxxx.exe"; info.arguments = "yyyyyyyyyy"; info.useshellexecute = true; info.createnowindow = true; info.windowstyle = processwindowstyle.maximized; info.redirectstandardinput = false; info.redirectstandardoutput = false; info.redirectstandarderror = false; system.diagnostics.process p = system.diagnostics.process.start(info); p.waitforinputidle(); thread.sleep(3000); process[] p1 ; if(p.mainwindowhandle == null) { list<string> arrstring = new list<string>(); foreach (process p1 in process.getprocesses()) { // console.writeline(p1.mainwindowhandle); arrstring.add(convert.tostring(p1.processname)); } p1 = process.getprocessesbyname("xxxxxxxxxxxx"); //p.waitforinputidle(); thread.sleep(5000); setparent(p1[0].mainwindowhandle, this.panel2.handle); } else { setparent(p.mainwindowhandle, this.panel2.handle); } </code></pre>

<p>еще одно интересное решение для внешнего приложения с контейнером winform заключается в следующем:</p><pre><code>[dllimport("user32.dll")] static extern intptr setparent(intptr hwndchild, intptr hwndnewparent); private void form1\_load(object sender, eventargs e) { processstartinfo psi = new processstartinfo("notepad.exe"); psi.windowstyle = processwindowstyle.minimized; process p = process.start(psi); thread.sleep(500); setparent(p.mainwindowhandle, panel1.handle); centertoscreen(); psi.windowstyle = processwindowstyle.normal; } </code></pre><p>шаг <code>processwindowstyle.minimized</code> из processwindowstyle.normal удалить раздражающую задержку.</p><p> <a href="https://i.stack.imgur.com/33yks.png"><img src="https://i.stack.imgur.com/33yks.png" alt="enter image description here"></a> </p>

<p>если вы хотите запустить блокнот внутри своего приложения, вам, вероятно, лучше использовать компонент текстового редактора. очевидно, что есть базовое текстовое поле, которое поставляется с winforms, но я подозреваю, что более широкие компоненты, которые предлагают функциональность notepad (или лучше), можно найти на веб-сайте.</p>

<p>я знаю, что это возможно, если другое приложение может присоединиться к дескриптору окна win32. например, у нас есть отдельное приложение c #, которое размещает приложение directx в одном из своих окон. я не знаком с точными деталями того, как это реализовано, но я думаю, что достаточно просто передать win32 <code>handle</code> вашей панели другому приложению, чтобы приложение прикрепило свою поверхность directx.</p>

<p>я заметил, что все предыдущие ответы используют более старые функции библиотеки win32 user для достижения этой цели. я думаю, что это будет работать в <em> большинстве </em> случаев, но со временем будет работать менее надежно.</p><p>теперь, не сделав этого, я не могу сказать вам, насколько хорошо это будет работать, но я знаю, что текущая технология windows может быть лучшим решением: <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540(v=vs.85).aspx">api windows desktop manager</a> .</p><p>dwm - это та же технология, которая позволяет просматривать в реальном времени миниатюры приложений с помощью панели задач и интерфейса переключателя задач. я считаю, что это тесно связано со службами удаленного терминала.</p><p>я думаю, что вероятная проблема, которая может возникнуть, когда вы заставляете приложение быть дочерним по отношению к родительскому окну, которое не является окном рабочего стола, состоит в том, что некоторые разработчики приложений делают предположения относительно контекста устройства (dc), положения указателя (мыши), ширины экрана и т. д., что может привести к ошибочному или проблематичному поведению, когда он "встроен" в главное окно.</p><p>я подозреваю, что вы можете в значительной степени устранить эти проблемы, полагаясь на dwm, который поможет вам управлять переводами, необходимыми для надежного представления окон приложения и взаимодействия с ними внутри окна контейнера другого приложения.</p><p>документация предполагает программирование на c++, но я нашел одного человека, который создал то, что, как он утверждает, является библиотекой оболочки c # с открытым исходным кодом: <a href="https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper">https://bytes.com/topic/c-sharp/answers/823547-desktop-window -manager-обертка</a> . пост старый, и его источник находится не в большом репозитории, таком как github, bitbucket или sourceforge, поэтому я не знаю, насколько он актуален.</p>