Windows 7 64bit・VS2005・C++で開発を行っていますが、
IOpenServiceのSetDefaultでIEの既定の検索プロバイダーを設定するダイアログを表示しようとすると
OS_E_CANCELLEDが返されキャンセル扱いとなりダイアログが表示されません。
Windows 7 for x64-based Systems 用 Internet Explorer 11 の累積的なセキュリティ更新プログラム (KB3160005)
https://www.microsoft.com/ja-jp/download/details.aspx?id=52911
をインストールするまでは表示されていましたのでこれが原因かと思いますが、対策を教えていただきたいのですが…
また、サンプルプログラムを用意しましたのでよろしければ確認いただけないでしょうか?
GoogleのIE検索プロバイダーをインストールしておく必要がありますが、
下記プログラムを実行するとGoogleを既定に設定します。
#define _WIN32_DCOM // CoInitializeEx
#include <windows.h>
#include <tchar.h>
#include <atlbase.h> // CComPtr
#include <objbase.h> // CoInitializeEx
#include <openservice.h>
#include <wininet.h> // INTERNET_MAX_URL_LENGTH
#include <atlutil.h>
HRESULT FindSearchProviderFromDomain(const TCHAR *pszDomain, BSTR *pbstrID);
HRESULT GuidToOpenServiceId(BSTR bstrGUID, BSTR *pbstrID);
BOOL ShowErrorMessage(HRESULT hr, const TCHAR *pszCaption);
#define DOMAIN _T("www.google.co.jp")
#define OSID_HEADER _T("x-osid:1:search:")
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, TCHAR *lpszCmdLine, int nCmdShow)
{
BSTR bstrID;
FindSearchProviderFromDomain(DOMAIN, &bstrID);
if(ShowErrorMessage(::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), _T("CoInitializeEx"))){
CComPtr<IOpenServiceManager> spManager;
if(ShowErrorMessage(spManager.CoCreateInstance(__uuidof(OpenServiceManager)), _T("CoCreateInstance"))){
CComPtr<IOpenService> spService;
if(ShowErrorMessage(spManager->GetServiceByID(bstrID, &spService), _T("GetServiceByID"))){
BOOL bIsDefault = FALSE;
if(ShowErrorMessage(spService->IsDefault(&bIsDefault), _T("IsDefault"))){
if(bIsDefault){
MessageBox(NULL, (CString)DOMAIN+_T("は既定のプロバイダーに設定されています"), _T("IsDefault"), MB_OK|MB_ICONINFORMATION);
}
else{
ShowErrorMessage(spService->SetDefault(TRUE, NULL), _T("SetDefault"));
}
}
}
}
}
::CoUninitialize();
return TRUE;
}
HRESULT FindSearchProviderFromDomain(const TCHAR *pszDomain, BSTR *pbstrID)
{
ATL::CRegKey reg;
LONG nResult = reg.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\SearchScopes"), KEY_READ);
if(nResult != ERROR_SUCCESS){
*pbstrID = ::SysAllocString(L"");
return S_OK;
}
CString sDomain(pszDomain);
sDomain = sDomain.MakeLower();
for(DWORD dwIndex=0; ; ++dwIndex){
TCHAR szKeyName[1024] = {};
DWORD dwKeyNameLen = _countof(szKeyName);
nResult = reg.EnumKey(dwIndex, szKeyName, &dwKeyNameLen);
if(nResult != ERROR_SUCCESS){
*pbstrID = ::SysAllocString(L"");
break;
}
ATL::CRegKey regSub;
LONG nResult = regSub.Open(reg.m_hKey, szKeyName, KEY_READ);
if(nResult != ERROR_SUCCESS) continue;
TCHAR szValue[INTERNET_MAX_URL_LENGTH] = {};
ULONG uChars = _countof(szValue);
nResult = regSub.QueryStringValue(_T("URL"), szValue, &uChars);
if(nResult != ERROR_SUCCESS) continue;
ATL::CUrl url;
if(!url.CrackUrl(szValue)) continue;
if(url.GetHostNameLength() == 0) continue;
CString sHostName(url.GetHostName());
sHostName = sHostName.MakeLower();
if(sHostName.Find(sDomain) >= 0){
HRESULT hr = GuidToOpenServiceId(szKeyName, pbstrID);
if(FAILED(hr)) return hr;
break;
}
}
reg.Close();
return S_OK;
}
HRESULT GuidToOpenServiceId(BSTR bstrGUID, BSTR *pbstrID)
{
const CString sGUID(bstrGUID);
TCHAR szEscaped[INTERNET_MAX_URL_LENGTH] = {};
DWORD chEscaped = _countof(szEscaped);
HRESULT hr = ::UrlEscape(sGUID, szEscaped, &cchEscaped, URL_ESCAPE_SEGMENT_ONLY);
if(FAILED(hr)) return hr;
CString sOsid(OSID_HEADER);
sOsid += szEscaped;
*pbstrID = sOsid.AllocSysString();
return S_OK;
}
BOOL ShowErrorMessage(HRESULT hr, const TCHAR *pszCaption)
{
switch(hr){
case S_OK:
return TRUE;
case OS_E_NOTFOUND:
MessageBox(NULL, _T("指定されたサービスが見つかりませんでした"), pszCaption, MB_OK|MB_ICONEXCLAMATION);
break;
case OS_E_NOTSUPPORTED:
MessageBox(NULL, _T("このアクションはサポートされていません"), pszCaption, MB_OK|MB_ICONEXCLAMATION);
break;
case OS_E_CANCELLED:
MessageBox(NULL, _T("キャンセルしました"), pszCaption, MB_OK|MB_ICONEXCLAMATION);
break;
case OS_E_GPDISABLED:
MessageBox(NULL, _T("グループポリシーはアクセラレーターを許可しません"), pszCaption, MB_OK|MB_ICONEXCLAMATION);
break;
default:
TCHAR szText[256];
wsprintf(szText, _T("0x%x"), hr);
MessageBox(NULL, szText, pszCaption, MB_OK|MB_ICONEXCLAMATION);
break;
}
return FALSE;
}
以上、よろしくお願いいたします。