// Does not exist on XP, shell32 is /delayload'ed // @pymethod <o PyIPropertyStore>|propsys|SHGetPropertyStoreFromParsingName|Retrieves the property store for an item by path static PyObject *PySHGetPropertyStoreFromParsingName(PyObject *self, PyObject *args) { // @comm This function does not exist on XP, even with Desktop Search installed PyObject *obpath, *obbindctx=Py_None; TmpWCHAR path; GETPROPERTYSTOREFLAGS flags=GPS_DEFAULT; IID riid=IID_IPropertyStore; IBindCtx *bindctx=NULL; void *ret=NULL; // @pyparm string|Path||Path to file // @pyparm <o PyIBindCtx>|BindCtx|None|Bind context, or None // @pyparm int|Flags|GPS_DEFAULT|Combination of GETPROPERTYSTOREFLAGS values (shellcon.GPS_*) // @pyparm <o PyIID>|riid|IID_IPropertyStore|The interface to return if (!PyArg_ParseTuple(args, "O|OkO&:SHGetPropertyStoreFromParsingName", &obpath, &obbindctx, &flags, PyWinObject_AsIID, &riid)) return NULL; if (!PyWinObject_AsWCHAR(obpath, &path, FALSE)) return NULL; if (!PyCom_InterfaceFromPyInstanceOrObject(obbindctx, IID_IBindCtx, (void **)&bindctx)) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = SHGetPropertyStoreFromParsingName(path, bindctx, flags, riid, &ret); if (bindctx) bindctx->Release(); PY_INTERFACE_POSTCALL; if (FAILED(hr)) return PyCom_BuildPyException(hr); return PyCom_PyObjectFromIUnknown((IUnknown *)ret, riid); }
extern "C" void __declspec(dllexport) Set(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) { g_stringsize = string_size; g_stacktop = stacktop; g_variables = variables; { IPropertyStore *m_pps = NULL; WCHAR wszPath[MAX_PATH]; WCHAR wszAppID[MAX_PATH]; TCHAR szPath[MAX_PATH]; TCHAR szAppID[MAX_PATH]; bool success = false; ZeroMemory(wszPath, sizeof(wszPath)); ZeroMemory(wszAppID, sizeof(wszAppID)); ZeroMemory(szPath, sizeof(szPath)); ZeroMemory(szAppID, sizeof(szAppID)); popstring(szPath, MAX_PATH); popstring(szAppID, MAX_PATH); #if !defined(UNICODE) MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH); #else wcscpy(wszPath, szPath); wcscpy(wszAppID, szAppID); #endif ::CoInitialize(NULL); if (SUCCEEDED(SHGetPropertyStoreFromParsingName(wszPath, NULL, GPS_READWRITE, IID_PPV_ARGS(&m_pps)))) { PROPVARIANT propvar; if (SUCCEEDED(InitPropVariantFromString(wszAppID, &propvar))) { if (SUCCEEDED(m_pps->SetValue(PKEY_AppUserModel_ID, propvar))) { if (SUCCEEDED(m_pps->Commit())) { success = true; } } } } if (m_pps != NULL) m_pps->Release(); CoUninitialize(); pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); } }
HRESULT GetPropertyStore(PCWSTR pszFilename, GETPROPERTYSTOREFLAGS gpsFlags, IPropertyStore** ppps) { WCHAR szExpanded[MAX_PATH]; HRESULT hr = ExpandEnvironmentStrings(pszFilename, szExpanded, ARRAYSIZE(szExpanded)) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); if (SUCCEEDED(hr)) { WCHAR szAbsPath[MAX_PATH]; hr = _wfullpath(szAbsPath, szExpanded, ARRAYSIZE(szAbsPath)) ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { hr = SHGetPropertyStoreFromParsingName(szAbsPath, NULL, gpsFlags, IID_PPV_ARGS(ppps)); } } return hr; }
HRESULT PrintShortcutProps(LPCWSTR aTargetPath) { HRESULT hres; ::CoInitialize(nullptr); IPropertyStore *m_pps = nullptr; if (FAILED(hres = SHGetPropertyStoreFromParsingName(aTargetPath, nullptr, GPS_READWRITE, IID_PPV_ARGS(&m_pps)))) { printf("SHGetPropertyStoreFromParsingName failed\n"); goto Exit; } bool found = false; PROPVARIANT propvar; if (SUCCEEDED(hres = m_pps->GetValue(PKEY_AppUserModel_IsDualMode, &propvar)) && propvar.vt == VT_BOOL && propvar.boolVal == -1) { printf("PKEY_AppUserModel_IsDualMode found\n"); PropVariantClear(&propvar); found = true; } if (SUCCEEDED(hres = m_pps->GetValue(PKEY_AppUserModel_ID, &propvar)) && propvar.pwszVal) { printf("PKEY_AppUserModel_ID found "); wprintf(L"value: '%s'\n", propvar.pwszVal); PropVariantClear(&propvar); found = true; } if (!found) { printf("no known properties found.\n"); } Exit: if (m_pps) { m_pps->Release(); } CoUninitialize(); return hres; }
HRESULT SetShortcutProps(LPCWSTR aShortcutPath, LPCWSTR aAppModelID, bool aSetID, bool aSetMode) { HRESULT hres; ::CoInitialize(nullptr); IPropertyStore *m_pps = nullptr; if (FAILED(hres = SHGetPropertyStoreFromParsingName(aShortcutPath, nullptr, GPS_READWRITE, IID_PPV_ARGS(&m_pps)))) { printf("SHGetPropertyStoreFromParsingName failed\n"); goto Exit; } if (aSetMode) { PROPVARIANT propvar; if (FAILED(hres = InitPropVariantFromBoolean(true, &propvar)) || FAILED(hres = m_pps->SetValue(PKEY_AppUserModel_IsDualMode, propvar))) { goto Exit; } PropVariantClear(&propvar); } if (aSetID && aAppModelID) { PROPVARIANT propvar; if (FAILED(hres = InitPropVariantFromString(aAppModelID, &propvar)) || FAILED(hres = m_pps->SetValue(PKEY_AppUserModel_ID, propvar))) { goto Exit; } PropVariantClear(&propvar); } hres = m_pps->Commit(); Exit: if (m_pps) { m_pps->Release(); } CoUninitialize(); return hres; }