// Use the following command to compile. // cl /MD /EHsc appumid.cpp // For Application User Model IDs documentation // see http://msdn.microsoft.com/en-us/library/dd378459%28VS.85%29.aspx #if 1 #define UNICODE #define _UNICODE #else #undef UNICODE #undef _UNICODE #endif #include #include #include #include // #include #include // #include // #include // #include #include // #include #include // #include #include // #pragma comment(lib, "user32.lib") // #pragma comment(lib, "shell32.lib") // #pragma comment(lib, "ole32.lib") // #pragma comment(lib, "comsupp.lib") #pragma comment(lib, "propsys.lib") #pragma comment(lib, "shlwapi.lib") _COM_SMARTPTR_TYPEDEF(IShellLink, IID_IShellLink); _COM_SMARTPTR_TYPEDEF(IPropertyStore, IID_IPropertyStore); #define PRINTF _tprintf #define ASSERT(x) do{ if(!(x)){ PRINTF(_T("ASSERT(%s) error at line %d of %s\n"), __LINE__, _T(__FILE__)); } }while(0) #define NUMBER_OF(x) (sizeof(x)/sizeof(*(x))) void ShowShellLinkAndChangeAppUserModel_ID(LPTSTR lnk_fname, LPTSTR app_id) { HRESULT hres; int len; IShellLinkPtr pSl; IPersistFilePtr pPf; IPropertyStorePtr pPs; wchar_t wsz_path[256]; wchar_t wsz_buf[256]; TCHAR buf[256]; int id; LPITEMIDLIST pidl; PROPVARIANT prop_variant = { VT_EMPTY }; pSl.CreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER); pPs = pPf = pSl; if(!pPs) goto leave; #ifndef _UNICODE len = MultiByteToWideChar(CP_ACP, 0, lnk_fname, -1, wsz_path, NUMBER_OF(wsz_path)); ASSERT(len != 0); #else _tcscpy(wsz_path, lnk_fname); #endif hres = pPf->Load(wsz_path, STGM_READWRITE); if(FAILED(hres)) goto leave; hres = pSl->GetPath(buf, NUMBER_OF(buf), NULL, SLGP_RAWPATH); if(FAILED(hres)) goto leave; if(buf[0] == 0){ PRINTF(_T("No Path\n")); }else{ PRINTF(_T("Path = %s\n"), buf); } hres = pSl->GetIconLocation(buf, NUMBER_OF(buf), &id); if(FAILED(hres)) goto leave; if(buf[0] == 0){ PRINTF(_T("No IconLocation\n")); }else{ PRINTF(_T("IconLocation = %s : %d\n"), buf,id); } hres = pSl->GetDescription(buf, NUMBER_OF(buf)); if(FAILED(hres)) goto leave; if(buf[0] == 0){ PRINTF(_T("No Description\n")); }else{ PRINTF(_T("Description = %s\n"), buf); } hres = pPs->GetValue(PKEY_AppUserModel_ID, &prop_variant); ASSERT(SUCCEEDED(hres)); hres = PropVariantToString(prop_variant, wsz_buf, NUMBER_OF(wsz_buf)); ASSERT(SUCCEEDED(hres)); PRINTF(_T("AppUserModel_ID = %ls\n"), wsz_buf); hres = PropVariantClear(&prop_variant); ASSERT(SUCCEEDED(hres)); if(!app_id) goto leave; if(app_id[0] != 0){ #ifndef _UNICODE len = MultiByteToWideChar(CP_ACP, 0, app_id, -1, wsz_buf, NUMBER_OF(wsz_buf)); ASSERT(len != 0); hres = InitPropVariantFromString(wsz_buf, &prop_variant); ASSERT(SUCCEEDED(hres)); #else hres = InitPropVariantFromString(app_id, &prop_variant); ASSERT(SUCCEEDED(hres)); #endif } hres = pPs->SetValue(PKEY_AppUserModel_ID, prop_variant); if(FAILED(hres)) goto leave; hres = PropVariantClear(&prop_variant); ASSERT(SUCCEEDED(hres)); hres = pPs->Commit(); if(FAILED(hres)) goto leave; hres = pPf->Save(wsz_path, TRUE); if(FAILED(hres)) goto leave; PRINTF(_T("Successfully changed AppUserModel_ID\n")); leave: ; } int _tmain( int argc, TCHAR **argv) { setlocale(LC_ALL, ""); if(argc < 2 || argc > 3){ PRINTF(_T("USAGE: appumid lnk_file [AppID]\n")); return 1; } CoInitialize(NULL); try{ if(argc == 2){ ShowShellLinkAndChangeAppUserModel_ID(argv[1], NULL); }else if(argc == 3){ ShowShellLinkAndChangeAppUserModel_ID(argv[1], argv[2]); } } catch(_com_error &e){ PRINTF(_T("_com_error: HRESULT = %08X\n"), e.Error()); } CoUninitialize(); return 0; }