C# 프로그램 패널 내에서 다른 응용 프로그램을 어떻게 실행할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/758494

문제

C# 프로그램 내부에서 응용 프로그램을 트리거하는 방법에 대해 많은 것을 읽었지만 (Process.start ()), C# 프로그램 패널 내 에서이 새로운 응용 프로그램을 실행하는 방법에 대한 정보를 찾을 수 없었습니다. . 예를 들어, 버튼을 클릭하여 외부가 아닌 응용 프로그램 내에서 Notepad.exe를 열어보십시오.

도움이 되었습니까?

해결책

이것이 여전히 사용되는 것이 권장되는지 모르겠지만 "객체 링크 및 포함"프레임 워크를 사용하면 응용 프로그램에 특정 객체/컨트롤을 직접 포함시킬 수 있습니다. 이것은 아마도 특정 애플리케이션에만 효과가있을 것입니다. 메모장이 그 중 하나인지 확실하지 않습니다. 메모장과 같은 간단한 것들의 경우 사용중인 매체 (예 : Winforms)에서 제공하는 텍스트 상자 컨트롤로 작업하는 데 더 쉬운 시간이있을 수 있습니다.

시작하려는 OLE 정보에 대한 링크는 다음과 같습니다.

http://en.wikipedia.org/wiki/object_linking_and_embedding

다른 팁

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에서 성가신 지연을 제거하십시오.

enter image description here

앱 내에서 메모장을 실행하려면 텍스트 편집기 구성 요소를 사용하는 것이 좋습니다. 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와 같은 큰 저장소에 있지 않으므로 현재 얼마나 현재인지 모르겠습니다.

짧은 대답:

아니

짧은 대답 :

다른 응용 프로그램이 허용하도록 설계된 경우에만 구성 요소를 제공하여 자신의 응용 프로그램에 추가 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top