1

I am iterating through a bunch of .lnk files and getting information on them.

For each file I do this, this is js-ctypes but is a winapi question. I removed the error checking and simplified the code:

var hr_CoInitializeEx = ostypes.API('CoInitializeEx')(null, ostypes.CONST.COINIT_APARTMENTTHREADED);

var shellLinkPtr = ostypes.TYPE.IShellLinkW.ptr();
var hr_CoCreateInstance = ostypes.API('CoCreateInstance')(ostypes.CONST.CLSID_ShellLink.address(), null, ostypes.CONST.CLSCTX_INPROC_SERVER, ostypes.CONST.IID_IShellLink.address(), shellLinkPtr.address());
shellLink = shellLinkPtr.contents.lpVtbl.contents;

var persistFilePtr = ostypes.TYPE.IPersistFile.ptr();
var hr_shellLinkQI = shellLink.QueryInterface(ostypes.CONST.IID_IPersistFile.address(), persistFilePtr.address());
persistFile = persistFilePtr.contents.lpVtbl.contents;

var propertyStorePtr = ostypes.TYPE.IPropertyStore.ptr();
var hr_shellLinkQI2 = shellLink.QueryInterface(ostypes.CONST.IID_IPropertyStore.address(), propertyStorePtr.address());
propertyStore = propertyStorePtr.contents.lpVtbl.contents;

for (var i = 0; i < arrOSPath.length; i++) {
    var hr_Load = persistFile.Load(persistFilePtr, arrOSPath[i], 0);

    var ppropvar = ostypes.TYPE.PROPVARIANT();
    var hr_GetValue = propertyStore.GetValue(ostypes.CONST.PKEY_AppUserModel_ID.address(), ppropvar.address());
    console.log(ppropvar.pwszVal); ////// <<<<< this is fishy

    var rez_PropVariantClear = ostypes.API('PropVariantClear')(ppropvar.address());
}

// cleanup
persistFile.Release(persistFilePtr);
propertyStore.Release(propertyStorePtr);
shellLink.Release(shellLinkPtr);
ostypes.API('CoUninitialize')();

However ppropvar.pwszVal is coming out to be the SystemAppUserModelID of the first file I IPersitFile::Loaded, is this expected? Do I have to CoUninitialize and CoInitialize each loop or something to fix this?

Thanks

Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • 1
    How is `references.persistFile` related to `pps`? Where and how are they both initialized? Please show a **complete** example. And please do not omit error checking. Chances are, either the subsequent loads are failing, or they are not reinitializing `pps` like you are expecting. You might need to use a new `pps` object for each file. – Remy Lebeau May 23 '15 at 18:19
  • Thanks @RemyLebeau very much for the attention. I clarified it by defining `pps` it is the `propertyStore` and added the stuff around it. The error checking I didnt add yet ill work on adding that in a pretty way, its very messy but i hope the so far stuff helps. :) its a bit messy cuz this is C++ from ctypes which is vtable work, it works great, just this really peculiar issue of not getting SystemAppUserModelID other then for the first one. – Noitidart May 23 '15 at 19:12
  • 1
    Why are you passing `propertyStorePtr` to `persistFile.Load()`? `Load`() does not take 4 parameters, even with a vtable. It takes 3 parameters, where the first parameter is the `persistFile` object. In any case, did you try creating and releasing a new `shellLink` object (and its secondary interfaces) inside the loop instead of outside the loop? I have seen many examples of calling `Load()` on a `IShellLink` object, but never an example of calling `Load()` multiple times on the same object. `Load()` is usually called on a new object. – Remy Lebeau May 23 '15 at 20:08
  • Thanks @RemyLebeau sorry thats why I provided cleaned up code in the first version, i forgot to take that out in second version :P thats required for interacting with vtable pointers from ctypes :P I removed those, they are non-issue for sure :) – Noitidart May 23 '15 at 20:46

0 Answers0