none
VISTA COMの昇格について RRS feed

  • 質問

  •  

    お世話になっております。

     

    COM昇格モニカのサンプルプログラムを用いて動作検証を行っているのですが、

    エラーとなってしまいます。

     

    http://blogs.msdn.com/vistacompatteam/archive/2006/09/28/CoCreateInstanceAsAdmin-or-CreateElevatedComObject-sample.aspx

     

    のサンプルソースをダウンロードして、XPでコンパイルをし、セットアッププログラムを作成し

    なんとかVISTAで動作するようにとしているのですが、動作しません。

    ※モジュールだけもっていっても、VC80CRT、VC80ATLがないなどど怒られました。。

     

    レジストリの登録などはうまくいっており・・・・

     //first create non-elevated
        hr =  CoCreateInstance(CLSID_TheElevated, NULL, CLSCTX_LOCAL_SERVER, IID_ITheElevated, (void**)&theElevated );

     hr = theElevated->ShowMe();
     
    上記では正しく動作するのですが、

     

     hr =  CoGetObject(wszCLSID, &bo, IID_ITheElevated, (void**)&theElevated );

     hr = theElevated->ShowMe();

    で失敗します。

     

    VISTA上で成功したいのですが、ご教授ください。

     

    開発環境は、VC2005を使用しております。

     

     

     



     

    2008年6月10日 11:31

回答

  • XP上のVisual C++ 2005 SP1においてダウンロードしたファイルをビルドし、Vista SP1に持って行って試したところ問題ありませんでした。

     

    試行手順

    1.XPでビルド。

    2.Vista SP1に再頒布パッケージをインストール。(VC80CRT等のインストーラ)

    VC++ 2005 SPなし:http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&DisplayLang=ja

    VC++ 2005 SP1:http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=ja

    3.Vistaのコマンドプロンプトを管理者モードで実行。

    4.regsvr32 MyElevatedCom.dllというコマンドを実行してレジストリに登録。

    5.TheComElevator.exeを実行。

    6.1度目のメッセージを閉じた後、昇格ダイアログが出たので承認。

    7.問題なく2度目のメッセージも表示。

     

    解決するために

    原因を突き止めるために、その失敗した際の、hrの値を取得、出力(あるいは表示)できるようにして下さい。

    そのエラーコードから何が原因なのか絞り込める余地があると考えます。

    もちろん、CoGetObjectが失敗していると推測されるので、その戻り値を取得するべきでしょう。
    2008年6月10日 14:33
    モデレータ

すべての返信

  • XP上のVisual C++ 2005 SP1においてダウンロードしたファイルをビルドし、Vista SP1に持って行って試したところ問題ありませんでした。

     

    試行手順

    1.XPでビルド。

    2.Vista SP1に再頒布パッケージをインストール。(VC80CRT等のインストーラ)

    VC++ 2005 SPなし:http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&DisplayLang=ja

    VC++ 2005 SP1:http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=ja

    3.Vistaのコマンドプロンプトを管理者モードで実行。

    4.regsvr32 MyElevatedCom.dllというコマンドを実行してレジストリに登録。

    5.TheComElevator.exeを実行。

    6.1度目のメッセージを閉じた後、昇格ダイアログが出たので承認。

    7.問題なく2度目のメッセージも表示。

     

    解決するために

    原因を突き止めるために、その失敗した際の、hrの値を取得、出力(あるいは表示)できるようにして下さい。

    そのエラーコードから何が原因なのか絞り込める余地があると考えます。

    もちろん、CoGetObjectが失敗していると推測されるので、その戻り値を取得するべきでしょう。
    2008年6月10日 14:33
    モデレータ
  • ご返事ありがとうございました。

     

    もう一度、Azulean さんの試行手順を見習ってもう一度行いました。

    結果、正しく動作しました。

     

    「検証」

    いろいろ納得できないのですが、

    1.モジュールだけのコピーの場合

    あらかじめ再配布パッケージをインストール必要があり、インストールしていない場合、regsvr32で失敗する。

     

    2.セットアッププロジェクトを作成

    VC80ATL、VC80CRTのマージモジュールを含め、インストールを行った。

    「vsdrfCOM」オプションではインストール中は特にエラーはでなくて、「vsdrfCOMSelfReg」はインストール中にエラーがでた。

    どちらもレジストリは設定されていなかった。

     

    とりあえずインストールを完了して(エラーが出たほうもう無視して完了させた)、EXEを起動して失敗するのを確認してから

    コマンドプロンプトで管理者モードで起動して、regsvr32を実行して登録した。

    再度EXEを起動すると正常に動作しました。

     

    「検証結果(納得いきませんが)」

    この内容から、VC80ATL、VC80CRTがインストールされていないと問題がおこると判断できます。

    納得いかないとは、昨日は、これらがインストールされて、regsvr32も正常に実行されても動作しなかったところです。

    おそらく、整理しないままいろんなことを試して別の問題が発生していたかもしれませんが。私のミスかもしれません。

     

    「セットアッププログラムの問題点」

    「vsdrfCOMSelfReg」は実際は、regsvr32と同じことをするはずなので、再配布モジュール(VC80ATL、VC80CRT)が

    インストールされているうえで実行されてなければならない。

     

    「vsdrfCOM」を使うべきっぽいのですが。。。わかりません。いまのところ。

    この問題と趣旨がずれているので。とりあえず深く追求せず。

     

     

     

    下記は私の試行手順です。

     

    試行手順

    1.プロジェクトのビルド

    XP(SP3) 、VC++2005SP1で上記プロジェクトを開きコンパイルしました。

    このままプロジェクトを開き、コンパイルするとコンパイルエラーが発生するので、

    TheComElevator.cppを一部修正しました。

     

     // 追記

    #define _WIN32_WINNT 0x0500

     :

    #include <windows.h>

     :

    // 追記

    typedef struct tagBIND_OPTS3 : tagBIND_OPTS2
    {
        HWND hwnd;
    } BIND_OPTS3, * LPBIND_OPTS3;

     

    int main(・・・)

     

    // 修正※アドバイスどおり戻り値を表示するよう修正しました。

     hr =  CoGetObject(wszMonikerName, &bo, IID_ITheElevated, (void**)&theElevated );
     if(SUCCEEDED(hr))
     {
      hr = theElevated->ShowMe();
      theElevated->Release();
     }else
     {
      WCHAR  szMessage[100];
      swprintf_s(szMessage,L"0x%x",hr);
      MessageBox(hwnd,szMessage,L"test",MB_OK);
     }

    再度ビルドを行い、正常にビルドが終了しました。

    ※VC2005からは、標準ライブラリをつかうと警告がでるんですね。

     

    2.VISTA環境の整備※但しVirtualPC-VISTA

     ・最新の更新プログラム(WindowsUpdate)をあてる

     ・再頒布パッケージをインストール。(VC80CRT等のインストーラ)

     ・上記モジュール(TheComElevator.exe、MyElevatedCom.dll)をコピー

     

    3.MyElevatedCom.dllのレジストリ登録

     ・コマンドプロンプトを管理者モードで開き、regsvr32を実行(正常終了)

     

    4.TheComElevator.exeの実行

     ・「first create non-elevated」は、成功

     ・「now create with elevation moniker」

      CoGetObject(・・・)関数の戻り値が、

     

    諸問題は残っておりますが、これらを解析して、VC6で作成したアプリが、HKEY_LOCAL_MACHINEへ

    書き込みアクセスをおこなっているところがあるので、これらをうまいことくみあわすことができたらと

    おもっております。。。

     

    ありがとうございました。

     

     

     

     

     
     
     
    2008年6月11日 3:09
  • 自己レスです。

     

    作成されたDLL(COM)をセットアッププログラムに含め、「vsdrfCOM」オプションをつけても

    解析しくれないみたいです。

    別のDLL(COM)で試すと解析しているので、rgsの書き方に問題があるのかもしれません。

     

    作成されたMSIファイルを解析しても、ないようでした。

     

    ・・・

    2008年6月11日 5:23
  •  TAKAKUN さんからの引用

    「vsdrfCOMSelfReg」は実際は、regsvr32と同じことをするはずなので、再配布モジュール(VC80ATL、VC80CRT)が

    インストールされているうえで実行されてなければならない。

    なぜでしょうか?

    Visual Studioのセットアッププロジェクトであるならば、必須コンポーネントでVisual C++のランタイムが含まれているはずですので、ここで指定すると、COMSelfRegを実行するタイミングで既に再頒布モジュールが入っている状態になります。

    (Setup.exe実行時にランタイムの判定・インストールし、Windows Installerに移行してからSelfRegが実行される)

     

     

    但し、SP1のランタイムのインストール条件チェックに不具合があります。

    下記の記事を参考に、C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\product.xmlを更新する必要があります。

    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=2726126&SiteID=7

    2008年6月11日 15:17
    モデレータ