c#으로 rot(?).. 이미 열려있는 문서 컨트롤하기

안녕하세요?

전에 다른 분이 파이썬으로 rot에 대해 문의하셔서 답글을 보았는데요…

이걸 c#으로 할려면 어떻게 해야 할지 잘 모르겠는데…
이미 열려 있는 한글 문서를 선택해서 프로그램과 연결하는 방법이 c#으로 될거 같은데 가능할까요?

1개의 좋아요

안녕하세요 한컴디벨로퍼 운영자입니다.
관련하여 답변을 준비 중에 있사오니 잠시만 기다려주세요 :slight_smile:
감사합니다.

1개의 좋아요

안녕하세요 ^^
한글 컨트롤로 문의를 주셨는데 내용은 오토메이션 같아서 오토메이션 예제 전달 드립니다 ^^

c#에서도 win32 api 접근 가능하기때문에 rot를 이용해 한글 프로세스에 접근 가능합니다.

아래 예제는 c#에서 rot를 통해 떠있는 한글 2018 에 파일을 여는 예제를 작성해봤습니다.

감사합니다 ^^

        [DllImport("ole32.dll")]
        static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
        [DllImport("ole32.dll")]
        private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

        private void button3_Click(object sender, EventArgs e)
        {
             // get Running Object Table ...
            IRunningObjectTable Rot;
            GetRunningObjectTable(0, out Rot);

            // get enumerator for ROT entries
            IEnumMoniker monikerEnumerator = null;
            Rot.EnumRunning(out monikerEnumerator);

            IntPtr pNumFetched = new IntPtr();
            IMoniker[] monikers = new IMoniker[1];

            IBindCtx bindCtx;
            CreateBindCtx(0, out bindCtx);
            string name;

            while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0)
            {
                monikers[0].GetDisplayName(bindCtx, monikers[0], out name);

                if (name.CompareTo("!HwpObject.100.1") == 0)
                {
                    IHwpObject hwp;
                    object obj;
                    Rot.GetObject(monikers[0], out obj);
                    hwp = (IHwpObject)obj;
                    hwp.Open("f:\\page1.hwp", "", "");
                }
            }
        }
2개의 좋아요

내용에 의거하여 분류를 '한글 오토메이션’으로 변경하였습니다. 너른 양해 부탁 드립니다. :slight_smile:

2개의 좋아요

감사합니다.
한글 창을 여러개 띄워놓고 해봤는데요…
마지막 선택한 한글 창이 아니라 그 전의 창이 선택이 되는데…
여러개의 한글 창 중에 마지막에 선택되었던 창을 선택하는 방법이 있을까요?

일러스트나 인디자인 같은 경우 예를 들면
var doc = app.activeDocument;

이런식으로 해서 활성화되어 있는 문서를 선택하는 방법처럼요…

2개의 좋아요

가이드 문서의 IXHwpDocuments 부분을 확인해보시면, 아래와 같은 api를 지원하고있습니다.

Active_XHwpDocument(Property) Description
현재 활성화 상태인 도큐먼트 Object를 얻어온다.(IXHwpDocument)

감사합니다 ^^

2개의 좋아요

죄송하지만 말씀하신 가이드 문서 링크를 달아주시면 감사요 ㅠㅠ

image
이 부분인지…

image
이 부분인지…

마음이 급해서 그런지 눈에 안보이네요 ㅎㅎ

2개의 좋아요

안녕하세요,
HwpAutomation.pdf 입니다 ^^

2개의 좋아요

안녕하세요.
주신 예제 코드로 실행해보았는데

hwp = (IHwpObject)obj;

이부분에서 아래와 같은 에러가 발생합니다.

System.InvalidCastException
HResult=0x80004002
메시지=‘System.__ComObject’ 형식의 COM 개체를 인터페이스 형식 ‘HwpObjectLib.IHwpObject’(으)로 캐스팅할 수 없습니다. 해당 인터페이스를 지원하지 않습니다. (예외가 발생한 HRESULT: 0x80004002 (E_NOINTERFACE)) 오류로 인해 IID가 '{5E6A8276-CF1C-42B8-BCED-319548B02AF6}'인 인터페이스의 COM 구성 요소에서 QueryInterface를 호출하지 못했으므로 이 작업을 수행할 수 없습니다.

어디가 문제 일까요?

2개의 좋아요

안녕하세요,
c# 프로젝트에서 HwpObject 참조를 안해주신것 같습니다 ~

2개의 좋아요

아뇨 참조는 했습니다. 참조가 없으면 비주얼스튜디오에서 아예 오류로 빌드가 안됩니다.
찾아보았더니 인터페이스 오류는 버전 문제라고 하는데 (오피스의 경우 여러 버전을 설치하거나 다운그레이드 등에서 동일한 문제가 발생한다고 하네요. 해결은 레지스트리에서 안쓰는 버전 정보 삭제)
한글은 2018외에는 설치한 것도 없고 레지스트리 뒤져봐도 100번(2018)외에는 없는 것 같아서 헤매고 있습니다.
혹시 HwpObject 인터페이스 관련 정보가 레지스트리 어느 부분에 기록되는지 알 수 있을까요?

2개의 좋아요

해당 인터페이스는 ocx가 regsvr32를 통해 윈도우로 등록되는것으로 알고있습니다.
레지스트리 오류가 발생한것이면

한컴 기본 설정에서 기본값으로 설정을 실행히주시길 바랍니다.

그래도 정상 동작하시지 않으시면 관리자로 실행시킨 명령창에서 hwp.exe에 -regserver를 통해 한글 재등록을 해주시고 테스트 부탁드립니다.
감사합니다.

2개의 좋아요

네 감사합니다. 한글 재설치 후 해결되었습니다.
혹시 c#으로 된 예제는 없을까요? 링크 가보니 c#만 깨져있어서요.

2개의 좋아요

안녕하세요 한컴디벨로퍼 입니다. :slight_smile:
현재 홈페이지 해당 링크에 접속이 어려운 상황입니다 ㅠ 불편을 드려 죄송합니다.
대신 여기를 클릭하여 C# 가이드를 다운로드 받으실 수 있습니다. 참고 부탁드려요~

2개의 좋아요

저도 계속 에러났었는데. 재설치를 하면 되는거였군요…

2개의 좋아요

한가지 궁금한게…
hwp = HwpObject; 와
hwp = IHwpObject;
두개는 어떻게 다른건지 간단하게라도 알 수 있을까요?

2개의 좋아요

안녕하세요,
hwp = IHwpObejct로 사용하셔야할것 같습니다 ^^
IHwpObject는 com 객체로 사용 가능한 인터페이스의 정의입니다.

아래에서 HwpObject는 등록되어있는 네임이 HwpObject인것입니다.
name.CompareTo(“!HwpObject.100.1”)

2개의 좋아요

아직도 c#으로 ROT를 해결 못하고 있습니다 ㅠㅠ
참조 추가 : HwpObject 1.0 Type Library 추가했습니다.
사용중인 아래한글 버전은 2010 사용하고 있습니다.

if (name.CompareTo(“!HwpObject.100.1”) != 0)
이 부분이 해당 버전 찾는것 같은데 아래한글 버전별로 어떻게 수정해야 할지도 모르겠네요
2014, 2018, 2020, 2022, 2024 등등요…

아래 코드에서 잘못된 점을 지적해주시면 고맙겠습니다.
간단하게 떠있는 한글창에 글자 입력 테스트 하는 코드입니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HwpObjectLib;

namespace hwp_rot01
{
    public partial class Form1 : Form
    {
        [DllImport("ole32.dll")]
        static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
        [DllImport("ole32.dll")]
        private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

        HwpObject hwp = IHwpObejct();

        public Form1()
        {
            InitializeComponent();
        }

        private void Typing(IHwpObject hwp, string text)
        {
            var act = hwp.CreateAction("InsertText");
            var pset = act.CreateSet();
            pset.SetItem("Text", text);
            act.Execute(pset);
            hwp.Run("BreakPara");       //문단 나누기(Enter)
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // get Running Object Table ...
            IRunningObjectTable Rot;
            GetRunningObjectTable(0, out Rot);

            // get enumerator for ROT entries
            IEnumMoniker monikerEnumerator = null;
            Rot.EnumRunning(out monikerEnumerator);

            IntPtr pNumFetched = new IntPtr();
            IMoniker[] monikers = new IMoniker[1];

            IBindCtx bindCtx;
            CreateBindCtx(0, out bindCtx);
            string name;

            while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0)
            {
                monikers[0].GetDisplayName(bindCtx, monikers[0], out name);

                if (name.CompareTo("!HwpObject.100.1") != 0)
                {
                    IHwpObject hwp;
                    object obj;
                    Rot.GetObject(monikers[0], out obj);
                    hwp = (IHwpObject)obj;

                    Typing(hwp, "기존 실행중인 한글 창에 글자 입력하기");
                    // hwp.Open("f:\\page1.hwp", "", "");
                }
            }
        }
    }
}

오피스 버전별로 개체명이 다릅니다.

2010 : “!HwpObject.80.1”
2014 : “!HwpObject.90.1”
NEO : “!HwpObject.96.1”
2018 : “!HwpObject.100.1”
2020 : “!HwpObject.110.1”
2022 : “!HwpObject.120.1”
2024 : “!HwpObject.130.1”

2개의 좋아요

열려있는 문서에 테스트로 글자 입력할려고 하는데 아래처럼 했는데 아무런 반응이 없네요
원래는 위에 올린 내용처럼 함수만들어서 할려고 했는데 아무런 반응이 없어서
아래코드처럼 직접 글자 입력하는 내용을 넣었는데 안되네요.
아래처럼 하는게 아니고 다른 방법으로 해야 하나요?
한글 2020 사용중입니다.

 if (name.CompareTo("!HwpObject.110.1") == 0)
 {
     IHwpObject hwp;
     object obj;
     Rot.GetObject(monikers[0], out obj);
     hwp = (IHwpObject)obj;

     var act = hwp.CreateAction("InsertText");
     var pset = act.CreateSet();
     string text = "기존 실행중인 한글 창에 글자 입력하기";
     pset.SetItem("Text", text);
     act.Execute(pset);
     hwp.Run("BreakPara");       //문단 나누기(Enter)

     //Typing(hwp, "기존 실행중인 한글 창에 글자 입력하기");
     // hwp.Open("f:\\page1.hwp", "", "");
 }
1개의 좋아요