C# 프로그램 패널 내에서 다른 응용 프로그램을 어떻게 실행할 수 있습니까?
문제
C# 프로그램 내부에서 응용 프로그램을 트리거하는 방법에 대해 많은 것을 읽었지만 (Process.start ()), C# 프로그램 패널 내 에서이 새로운 응용 프로그램을 실행하는 방법에 대한 정보를 찾을 수 없었습니다. . 예를 들어, 버튼을 클릭하여 외부가 아닌 응용 프로그램 내에서 Notepad.exe를 열어보십시오.
해결책
이것이 여전히 사용되는 것이 권장되는지 모르겠지만 "객체 링크 및 포함"프레임 워크를 사용하면 응용 프로그램에 특정 객체/컨트롤을 직접 포함시킬 수 있습니다. 이것은 아마도 특정 애플리케이션에만 효과가있을 것입니다. 메모장이 그 중 하나인지 확실하지 않습니다. 메모장과 같은 간단한 것들의 경우 사용중인 매체 (예 : Winforms)에서 제공하는 텍스트 상자 컨트롤로 작업하는 데 더 쉬운 시간이있을 수 있습니다.
시작하려는 OLE 정보에 대한 링크는 다음과 같습니다.
다른 팁
Win32 API를 사용하면 다른 응용 프로그램을 "먹는"것이 가능합니다. 기본적으로 해당 애플리케이션의 상단 창을 얻고 부모가 배치하려는 패널의 손잡이로 설정합니다. MDI 스타일 효과를 원하지 않으면 창 스타일을 조정하여 최대화하고 최대화하고 제목 표시 줄을 제거하십시오.
버튼과 패널이있는 양식이있는 간단한 샘플 코드는 다음과 같습니다.
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);
}
}
방금 잠자는 대신 WaitforInputIdle이라고 불리는 또 다른 예를 보았습니다. 따라서 코드는 다음과 같습니다.
Process p = Process.Start("notepad.exe");
p.WaitForInputIdle();
SetParent(p.MainWindowHandle, panel1.Handle);
코드 프로젝트에는 좋은 기사가 전체 프로세스입니다. Winform 프로젝트에서 EXE 애플리케이션을 호스팅합니다
- 답변에 솔루션 추가 .. **
이 코드는 Windows 양식에 실행 파일을 도킹하는 데 도움이되었습니다. 메모장, Excel, Word, Acrobat Reader n처럼 많은 ...
그러나 일부 응용 프로그램에는 효과가 없습니다. 때로는 애플리케이션의 프로세스를 시작할 때처럼 .... 유휴 시간을 기다리며 메인 위도 핸들을 얻으려고 노력합니다 .... 메인 창 핸들이 널이 될 때까지 .....
그래서 나는 이것을 해결하기 위해 하나의 트릭을 수행했습니다
메인 창 핸들을 NULL로 가져 오면 ... SYTEM에서 모든 런닝 프로세스를 검색하고 프로세스를 찾으십시오. 그런 다음 프로세스의 기본 해들과 세트 패널을 부모로 얻으십시오.
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);
}
Winform 컨테이너가있는 Exeternal 응용 프로그램 Luch에 대한 또 다른 흥미로운 솔루션은 다음과 같습니다.
[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;
}
단계 ProcessWindowStyle.Minimized
ProcessWindowStyle에서 성가신 지연을 제거하십시오.
앱 내에서 메모장을 실행하려면 텍스트 편집기 구성 요소를 사용하는 것이 좋습니다. Winforms와 함께 제공되는 기본 텍스트 상자가 분명히 있지만, 메모장 기능을 제공하는 고급 구성 요소 (또는 더 나은)는 인터 웹에서 찾을 수 있다고 생각합니다.
다른 응용 프로그램이 Win32 창 손잡이에 첨부 될 수 있다면 이것이 가능하다는 것을 알고 있습니다. 예를 들어, Windows 중 하나에서 DirectX 응용 프로그램을 호스팅하는 별도의 C# 응용 프로그램이 있습니다. 나는 이것이 어떻게 구현되는지에 대한 정확한 세부 사항에 익숙하지 않지만 Win32를 통과하는 것만으로 생각합니다. Handle
다른 응용 프로그램에 대한 패널 중 해당 응용 프로그램이 DirectX 표면을 부착하기에 충분합니다.
모든 이전 답변은 이전 Win32 사용자 라이브러리 기능을 사용하여이를 달성합니다. 나는 이것이 효과가 있다고 생각한다 대부분 사례이지만 시간이 지남에 따라 덜 안정적으로 작동합니다.
이제이 작업을 수행하지 않았기 때문에 얼마나 잘 작동하는지 말할 수는 없지만 현재 Windows 기술이 더 나은 솔루션이 될 수 있다는 것을 알고 있습니다. 데스크탑 Windows Manager API.
DWM은 작업 표시 줄 및 작업 전환기 UI를 사용하여 앱의 라이브 썸네일 미리보기를 볼 수있는 동일한 기술입니다. 원격 터미널 서비스와 밀접한 관련이 있다고 생각합니다.
앱을 데스크탑 창이 아닌 부모 창의 자식으로 강요 할 때 발생할 수있는 가능한 문제는 일부 애플리케이션 개발자가 장치 컨텍스트 (DC), 포인터 (마우스) 위치에 대한 가정을 할 것입니다. 스크린 너비 등은 기본 창에 "내장"될 때 불규칙하거나 문제가있는 동작을 유발할 수 있습니다.
DWM에 의존하여 애플리케이션의 Windows를 안정적으로 제시하고 다른 응용 프로그램의 컨테이너 창과 상호 작용하는 데 필요한 번역을 관리하여 이러한 문제를 크게 제거 할 수 있다고 생각합니다.
이 문서는 C ++ 프로그래밍을 가정하지만 그가 주장한 것을 생산 한 사람이 오픈 소스 C# 래퍼 라이브러리라고 생각했습니다. https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper. 게시물은 오래되었고 소스는 Github, Bitbucket 또는 Sourceforge와 같은 큰 저장소에 있지 않으므로 현재 얼마나 현재인지 모르겠습니다.
아니
짧은 대답 :다른 응용 프로그램이 허용하도록 설계된 경우에만 구성 요소를 제공하여 자신의 응용 프로그램에 추가 할 수 있습니다.