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?
All shell interfaces require the apartment threaded model (COINIT_APARTMENTTHREADED), it also only exists on Vista and up.
Sorry! What exists only in Vista and uo? The shell interfaces or the apartment threaded model?
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
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?
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 (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 (http://msdn.microsoft.com/en-us/library/windows/desktop/ee330741%28v=vs.85%29.aspx)
Laur
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!
The interface is Vista plus. Shell interfaces have always required apartment threads.
On XP you can use IShellDispatch::ControlPanelItem (http://msdn.microsoft.com/en-gb/library/windows/desktop/gg537712(v=vs.85).aspx) but it doesn't work on Vista plus. They recommend you use laurro's method above, so I'd just use that.
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