用VC6创建了一个EXE的进程外组件,并自定义了接口IPicList和继承该接口的类,并在_tWinMain函数中调用了IPicList,并执行其函数。编译后直接运行EXE文件,结果很正常。现在我又创建了一个客户端,想调用EXE的进程外组件的接口IPicList的函数,所以我使用以下代码: CoInitialize(NULL);
IPicListPtr pPicList; HRESULT hr = pPicList.CreateInstance(__uuidof(PicList));发现客户端CreateInstance创建实例后EXE程序就直接跑起来了,并在其_tWinMain函数中调用了IPicList,而客户端还只是获取到接口指针,并没来得及调用接口的函数了,函数就已经运行了(也许这就是进程外的意义吧)。
其实我想创建一个EXE的进程外组件,其中的IPicList接口可以其自身调用,只是这个接口必须放在EXE的进程外组件的_tWinMain函数中运行,也可以供其他客户端调用而又不会启动_tWinMain函数。有什么好办法吗?

解决方案 »

  1.   

    EXE启动不可能不运行WinMain。可以通过命令行参数决定组件是被其它客户端启动还是直接被用户启动
      

  2.   


    但是客户端调用CreateInstance时EXE就已经启动了,无法传递命令行参数。
    以前看到一个用LoadLibrary dll COM库的例子,但是发现EXE的进程外组件没有导出函数,很郁闷。
    不知道EXE的进程外组件有没有什么标准解决方案
      

  3.   

    代码跟进程内一样先调用exe 参数执行注册
    然后运行exe
    其他程序创建对象
      

  4.   

    那就_tWinMain中不要直接运行,调用进程外只是启动组件,然后再调用对应接口方法
      

  5.   


    没明白我的意思。客户端调用CreateInstance时EXE就已经启动了,无法传递命令行参数。
      

  6.   


    你设计有问题,COM的调用者不需要知道实现者是进程内还是进程外,还是在远程机器上实现。
      

  7.   


    为什么是设计问题?我只想在进程外组件启动时也调用接口函数,客户端启动后也能调用而已。这样调用接口函数既可以自己执行显示对话框,也可以被客户端调用显示对话框。这样的设计应该没什么问题啊。是不是这样的效果通过COM的标准方式无法解决,而一定要进程通信并设“标志”位才行?如果一个dll、EXE有导出函数,那其他客户端可以通过LoadLibrary的方式加载,而不一定要启动程序。如果COM的加载方式也能实现以上所述的方式就好了。
      

  8.   

    呃,原来是这个意思。可以实现,就是2楼的方法。atl默认处理了 RegServer UnregServer
    其他的时候你就可以创建com对象了。不过要注意时间,不是任何时间都能够创建成功的。
      

  9.   

        int nRet = 0;
        BOOL bRun = TRUE;
        LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
        while (lpszToken != NULL)
        {
            if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
            {
                _Module.UpdateRegistryFromResource(IDR_ProcessManager, FALSE);
                nRet = _Module.UnregisterServer(TRUE);
                bRun = FALSE;
                break;
            }
            if (lstrcmpi(lpszToken, _T("RegServer"))==0)
            {
                _Module.UpdateRegistryFromResource(IDR_ProcessManager, TRUE);
                nRet = _Module.RegisterServer(TRUE);
                bRun = FALSE;            break;
            }
            lpszToken = FindOneOf(lpszToken, szTokens);
        }
    你说的是上面那段进程外组件自带的代码吧!该怎么传递你说的命令行?麻烦你说细点,谢谢。客户端调用CreateInstance时EXE就已经启动了,无法传递命令行参数啊。
      

  10.   

    这是COM设计的行为,如果不想启动进程,就做成COM dll
    也可以做成service,这样不用每次启动一个进程
      

  11.   

    无法为进程外组件传递命令行参数,因为进程外组件的启动是由 COM 库完成的。但是你的问题也不难解决。COM 库在启动进程外组件时会为进程传递“Embedded”命令行参数。
    在你的程序中可以通过检查命令行来判断自己的应用程序是独立运行还是作为服务组件运行。if(lpCmdLine 不包含 Embedded)
    {
        // 独立运行方式,立即调用接口显示对话框
        ...
        ...
    }
    else
    {
        // 组件运行方式,Do nothing...
    }
      

  12.   


    thanks,就是要这个BTW 命令行参数是"Embedding"