本帖最后由 langshanglibie 于 2014-01-28 15:09:08 编辑

解决方案 »

  1.   

    对象release的时候可能还需要其他操作
    执行CoUninitialize后,可能操作就无法结束,就崩溃了。所以不管什么代码,都用{}括起来
      

  2.   

    一个先后顺序,CoUninitialize要在最后执行。它先执行就可能影响COM接口等
      

  3.   

    那为什么这样就不会挂掉?
    int _tmain(int argc, _TCHAR* argv[])
    {
    CoInitialize(NULL); CComPtr<IShellDispatch> spShellDispatch;
    HRESULT hr = spShellDispatch.CoCreateInstance(CLSID_Shell);
    if ( SUCCEEDED(hr) )
    {
    spShellDispatch->SetTime();
    } CoUninitialize(); return 0;
    }
      

  4.   


    那为什么这样就不会挂掉?int _tmain(int argc, _TCHAR* argv[])
    {
    CoInitialize(NULL); CComPtr<IShellDispatch> spShellDispatch;
    HRESULT hr = spShellDispatch.CoCreateInstance(CLSID_Shell);
    if ( SUCCEEDED(hr) )
    {
    spShellDispatch->SetTime();
    } CoUninitialize(); return 0;
    }
      

  5.   

    照理说着两个玩意编译完成一样,不应该挂。怀疑IWindowsShell的SetTime是不是异步的,但也说不通,难道多了一个指令之后就能正常运行了?你不妨 CoUninitialize之前sleep下试试
      

  6.   


    我把现象在说一遍吧:这两个玩意都能他们弹出
    时间框,但是没有花括号的代码在智能指针析构的时候就挂了
    ~CComPtrBase() throw()
    {
        if (p)
            p->Release(); // 运行这句的时候挂了!
    }
    试了你的方法,我在CoUninitialize之前Sleep(5000),还是不行。
      

  7.   

    不调用CoUninitialize是没问题的
      

  8.   


    我把现象在说一遍吧:这两个玩意都能他们弹出
    时间框,但是没有花括号的代码在智能指针析构的时候就挂了
    ~CComPtrBase() throw()
    {
        if (p)
            p->Release(); // 运行这句的时候挂了!
    }
    试了你的方法,我在CoUninitialize之前Sleep(5000),还是不行。
    是这个意思啊,那就是析构的问题啊,你这个IWindowsShell明显是在CoUninitialize之后析构了,因此崩溃了,至于IShellDispatch为什么没崩溃,很可能他是CoUninitialize之前做了什么特殊处理(也有可能它本身内部做了什么处理),因此没有崩溃,验证方法就是在p->Release();这里下个断点就能看见。
      

  9.   


    是的,IShellDispatch在p->Release();没有崩溃,而我的代码在p->Release();就崩溃了。
    如果是IShellDispatch做了特殊处理,那做了什么特殊处理啊?
    那如果我们不知道做了什么特殊处理,当使用CComPtr的时候就只能多多使用花括号了啊?
      

  10.   


    是的,IShellDispatch在p->Release();没有崩溃,而我的代码在p->Release();就崩溃了。
    如果是IShellDispatch做了特殊处理,那做了什么特殊处理啊?
    那如果我们不知道做了什么特殊处理,当使用CComPtr的时候就只能多多使用花括号了啊?

    单独写一个函数,这样局部变量在函数结束时就析构了