Class not registered

Started by czerny, September 30, 2014, 05:59:43 PM

Previous topic - Next topic

czerny

I have the error:

0x80040154 Class not registered error

after the following sequence:


IOpenControlPanel *pocp;

hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER, &IID_IOpenControlPanel, (void **)&pocp);


Is it really possible, that IOpenControlPanel class is not registered? Or is there something else wrong?

aardvajk

All shell interfaces require the apartment threaded model (COINIT_APARTMENTTHREADED), it also only exists on Vista and up.

czerny

Sorry! What exists only in Vista and uo? The shell interfaces or the apartment threaded model?

laurro

The IOpenControlPanel interface, and many others shell interfaces but not all,
exist only for Vista and above, see the minimum system requirement.
Tested on my Vista machine:


#include <windows.h>
#include <shobjidl.h>
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"uuid.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
IOpenControlPanel *p;

HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER, &IID_IOpenControlPanel, (void **)&p);
if (SUCCEEDED(hr))
{
hr = p->lpVtbl->Open(p, L"Microsoft.Personalization", L"pageColorization", NULL);
p->lpVtbl->Release(p);
}
}
CoInitialize(NULL);
return 0;
}



Laur

czerny

Quote from: czerny on September 30, 2014, 07:48:06 PM
Sorry! What exists only in Vista and uo? The shell interfaces or the apartment threaded model?
Is there an alternative in w2k/XP?

laurro

#5
As a COM ? I don't think so. But you can try ShellExecute().


#include <windows.h>
#include <shellapi.h>
#pragma comment(lib,"shell32.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
//ShellExecute(NULL, "open", "control", "/name Microsoft.Personalization /page pageColorization", NULL, SW_SHOW);
//ShellExecute(NULL, "open", "control", "/name Microsoft.DateAndTime", NULL, SW_SHOW);
ShellExecute(NULL, "open", "control", "timedate.cpl", NULL, SW_SHOW);
return 0;
}


see
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144191%28v=vs.85%29.aspx#opening_a_control_panel_item_from_the_command_line_with_control.exe
and
http://msdn.microsoft.com/en-us/library/windows/desktop/ee330741%28v=vs.85%29.aspx


Laur

czerny

Quote from: laurro on October 01, 2014, 09:12:19 AM
As a COM ? I don't think so. But you can try ShellExecute().
I know this way! Thanks!

aardvajk

The interface is Vista plus. Shell interfaces have always required apartment threads.
On XP you can use IShellDispatch::ControlPanelItem but it doesn't work on Vista plus. They recommend you use laurro's method above, so I'd just use that.

laurro

#8
Hi aardvajk
For a method that supposedly does not work, well, I have to close a lot of windows.
Of course it is not your fault, the documentation is wrong and I'm pretty sure is
wrong intentionally. If you have Vista or 7 (x86) run this, I'm not sure on 64 bit
systems, I don't have the possibility to test.


#define UNICODE
#include <windows.h>
#include <shobjidl.h>
#include <shldisp.h>
#include <wchar.h>
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"oleaut32.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
wchar_t first[MAX_PATH] = { 0 };
wchar_t *expand = malloc(sizeof(wchar_t));
if (expand)
{
DWORD d = ExpandEnvironmentStrings(L"%SystemRoot%", expand, 1);
expand = realloc(expand, d * sizeof(wchar_t));
if (expand)
{
ExpandEnvironmentStrings(L"%SystemRoot%", expand, d);
wcscpy(first, expand);
wcscat(first, L"\\System32\\*.cpl");
free(expand);
}
else
return 0;
}
else
return 0;
hSearch = FindFirstFile(first, &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
return 0;
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr))
{
FindClose(hSearch);
return 0;
}
/////////////////////
IShellDispatch *shell;
/////////////////////
hr = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void **)&shell);
if (FAILED(hr))
{
FindClose(hSearch);
CoInitialize(NULL);
return 0;
}
hr = shell->lpVtbl->ControlPanelItem(shell, FileData.cFileName);
while (1)
{
if (FindNextFile(hSearch, &FileData))
{
hr = shell->lpVtbl->ControlPanelItem(shell, FileData.cFileName);
if (FAILED(hr))
MessageBox(NULL, L"error", FileData.cFileName, MB_OK);
}
else
break;
}
shell->lpVtbl->Release(shell);
FindClose(hSearch);
CoInitialize(NULL);
return 0;
}



Laur