如何连接到已打开的WORD(不知是否很难)

yayafu 2013-06-24 12:30:48
_Application WordApp; //代表WORD程序

if(!WordApp.CreateDispatch("Word.Application",NULL))//创建一个新的word程序
上面的程序是很多例子都会使用的,这样是创建一个新WORD实例,而我想要的是如果机子上WORD已启动,就不要再启动WORD,而是将WordApp连接到已启动的WORD实例.
有大虾知道吗?
...全文
173 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
redui 2013-06-25
  • 打赏
  • 举报
回复
看到C#代码有点蛋疼,赶脚写的代码比C++还多
  • 打赏
  • 举报
回复
围观
pc_stone 2013-06-24
  • 打赏
  • 举报
回复


using System;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Collections;

#region TestROT Class

/// <summary>
/// Test ROT class showing how to use the ROTHelper.
/// </summary>
class TestROT
{


    //static void Test()
    //{ 
    //UCOMIBindCtx
    //}
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {

        // Iterate through all the objects in the ROT
        Hashtable runningObjects = ROTHelper.GetActiveObjectList(null);
        // Display the object ids
        foreach (DictionaryEntry de in runningObjects)
        {
            string progId = de.Key.ToString();
            if (progId.IndexOf("{") != -1)
            {
                // Convert a class id into a friendly prog Id
                progId = ROTHelper.ConvertClassIdToProgId(de.Key.ToString());
            }
            Console.WriteLine(progId);
            object getObj = ROTHelper.GetActiveObject(progId);
            if (getObj != null)
            {
                Console.WriteLine("Fetched: " + progId);
            }
            else
            {
                Console.WriteLine("!!!!!FAILED TO fetch: " + progId);
            }
        }
        Console.ReadLine();
    }
}
#endregion TestROT Class

#region ROTHelper Class

/// <summary>
/// The COM running object table utility class.
/// </summary>
public class ROTHelper
{
    #region APIs

    [DllImport("ole32.dll")]
    private static extern int GetRunningObjectTable(int reserved,
        out UCOMIRunningObjectTable prot);

    [DllImport("ole32.dll")]
    private static extern int CreateBindCtx(int reserved,
        out UCOMIBindCtx ppbc);

    [DllImport("ole32.dll", PreserveSig = false)]
    private static extern void CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] string progId, out Guid clsid);

    [DllImport("ole32.dll", PreserveSig = false)]
    private static extern void CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] string progId, out Guid clsid);

    [DllImport("ole32.dll")]
    private static extern int ProgIDFromCLSID([In()]ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)]out string lplpszProgID);

    #endregion

    #region Public Methods

    /// <summary>
    /// Converts a COM class ID into a prog id.
    /// </summary>
    /// <param name="progID">The prog id to convert to a class id.</param>
    /// <returns>Returns the matching class id or the prog id if it wasn't found.</returns>
    public static string ConvertProgIdToClassId(string progID)
    {
        Guid testGuid;
        try
        {
            CLSIDFromProgIDEx(progID, out testGuid);
        }
        catch
        {
            try
            {
                CLSIDFromProgID(progID, out testGuid);
            }
            catch
            {
                return progID;
            }
        }
        return testGuid.ToString().ToUpper();
    }

    /// <summary>
    /// Converts a COM class ID into a prog id.
    /// </summary>
    /// <param name="classID">The class id to convert to a prog id.</param>
    /// <returns>Returns the matching class id or null if it wasn't found.</returns>
    public static string ConvertClassIdToProgId(string classID)
    {
        Guid testGuid = new Guid(classID.Replace("!", ""));
        string progId = null;
        try
        {
            ProgIDFromCLSID(ref testGuid, out progId);
        }
        catch (Exception)
        {
            return null;
        }
        return progId;
    }

    /// <summary>
    /// Get a snapshot of the running object table (ROT).
    /// </summary>
    /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object
    /// <param name="filter">The filter to apply to the list (nullable).</param>
    /// <returns>A hashtable of the matching entries in the ROT</returns>
    public static Hashtable GetActiveObjectList(string filter)
    {
        Hashtable result = new Hashtable();
        
        int numFetched;
        UCOMIRunningObjectTable runningObjectTable;
        UCOMIEnumMoniker monikerEnumerator;
        UCOMIMoniker[] monikers = new UCOMIMoniker[1];

        GetRunningObjectTable(0, out runningObjectTable);
        runningObjectTable.EnumRunning(out monikerEnumerator);
        monikerEnumerator.Reset();

        while (monikerEnumerator.Next(1, monikers, out numFetched) == 0)
        {
            UCOMIBindCtx ctx;
            CreateBindCtx(0, out ctx);

            string runningObjectName;
            monikers[0].GetDisplayName(ctx, null, out runningObjectName);

            object runningObjectVal;
            runningObjectTable.GetObject(monikers[0], out runningObjectVal);
            if (filter == null || filter.Length == 0 || filter.IndexOf(filter) != -1)
            {
                result[runningObjectName] = runningObjectVal;
            }
        }

        return result;
    }

    /// <summary>
    /// Returns an object from the ROT, given a prog Id.
    /// </summary>
    /// <param name="progId">The prog id of the object to return.</param>
    /// <returns>The requested object, or null if the object is not found.</returns>
    public static object GetActiveObject(string progId)
    {
        // Convert the prog id into a class id
        string classId = ConvertProgIdToClassId(progId);

        UCOMIRunningObjectTable prot = null;
        UCOMIEnumMoniker pMonkEnum = null;
        try
        {
            int Fetched = 0;
            // Open the running objects table.
            GetRunningObjectTable(0, out prot);
            prot.EnumRunning(out pMonkEnum);
            pMonkEnum.Reset();
            UCOMIMoniker[] pmon = new UCOMIMoniker[1];

            // Iterate through the results
            while (pMonkEnum.Next(1, pmon, out Fetched) == 0)
            {
                UCOMIBindCtx pCtx;

                CreateBindCtx(0, out pCtx);

                string displayName;
                pmon[0].GetDisplayName(pCtx, null, out displayName);
                Marshal.ReleaseComObject(pCtx);
                if (displayName.IndexOf(classId) != -1)
                {
                    // Return the matching object
                    object objReturnObject;
                    prot.GetObject(pmon[0], out objReturnObject);
                    return objReturnObject;
                }
            }
            return null;
        }
        finally
        {
            // Free resources
            if (prot != null)
                Marshal.ReleaseComObject(prot);
            if (pMonkEnum != null)
                Marshal.ReleaseComObject(pMonkEnum);
        }
    }

    #endregion
}

#endregion
pc_stone 2013-06-24
  • 打赏
  • 举报
回复
我也在问你说的问题: http://bbs.csdn.net/topics/390497528
redui 2013-06-24
  • 打赏
  • 举报
回复
如果只有一个WORD实例在运行,可以直接用GetActiveObject获得这个WORD的_Application对象。 如果有多个WORD实例在运行,则上面这招不管用,过程更加复杂一点: 先用GetRunningObjectTable获取全局唯一的IRunningObjectTable接口 调用 IRunningObjectTable::EnumRunning 获得一个所有运行对象的IMoniker枚举器接口(IEnumMoniker) 循环调用IEnumMoniker::Next遍历,每次调用获取到一个运行对象的IMoniker接口,对这个接口必须要做两个判断,一个是它是你需要的对象类型(比如Word.Application)吗?另一个是它打开的文档是你关注的吗?如果不关注,你可以忽略它继续循环遍历下去,直至找到为止。判断方法如下: 调用 IMoniker::GetClassID,看看获得的CLSID是不是跟WORD.Application对应的CLSID相同,只有相同的才说明它是一个WORD应用对象。 第二个判断条件那就是八仙过海各显神通了,完全依据应用类型来定,如果已经知道它是WORD应用对象了,那么调用 IRunningObjectTable::GetObject 就可以得到这个IMoniker对应的实际接口了,然后通过QI查询出 _Application 接口(查不出当然就不是WORD对象了),查出来后通过 GetDocument 之类的方法去一步步检索文档的路径,看看它打开的文档是不是你想要的,不想要的果断放弃,继续遍历。。。 码字真累

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧