Reading a PROPVARIANT seems innocuous, but it suffers from many of the same dangers as does initializating one of these structures.  I highly recommend that you instead use the following helpers to aid your code's readability and reduce your error rate.

If the data is not exactly the right type, these functions attempt to convert the type to what you've asked for.  String <-> Integer, and Integer <-> Integer conversions are supported, along with a few others.  The conversions should be locale-invariant, so don't depend on the conversions to provide display strings.  I'll talk about the details in future posts (... note to self ...)

I've marked the ideal VARTYPE for each function.  If the PROPVARIANT is already of that type, a conversion is not necessary.

// Basic types
PSSTDAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, __out BOOL *pfRet);      // VT_BOOL
PSSTDAPI
PropVariantToInt16(REFPROPVARIANT propvarIn, __out SHORT *piRet);       // VT_I2
PSSTDAPI
PropVariantToUInt16(REFPROPVARIANT propvarIn, __out USHORT *puiRet);    // VT_UI2
PSSTDAPI
PropVariantToInt32(REFPROPVARIANT propvarIn, __out LONG *plRet);        // VT_I4
PSSTDAPI
PropVariantToUInt32(REFPROPVARIANT propvarIn, __out ULONG *pulRet);     // VT_UI4
PSSTDAPI
PropVariantToInt64(REFPROPVARIANT propvarIn, __out LONGLONG *pllRet);   // VT_I8
PSSTDAPI
PropVariantToUInt64(REFPROPVARIANT propvarIn, __out ULONGLONG *pullRet);// VT_UI8
PSSTDAPI
PropVariantToDouble(REFPROPVARIANT propvarIn, __out DOUBLE *pdblRet);   // VT_R8
PSSTDAPI
PropVariantToBuffer(REFPROPVARIANT propvar, __out_bcount(cb) void *pv, UINT cb);   // VT_VECTOR | VT_UI1

// Strings and things
PSSTDAPI PropVariantToString(REFPROPVARIANT propvar, __out_ecount(cch) PWSTR psz, UINT cch);     // VT_LPWSTR or VT_BSTR
HRESULT
PropVariantToBSTR(REFPROPVARIANT propvar, __out BSTR *pbstrOut);          // VT_LPWSTR or VT_BSTR
HRESULT
PropVariantToStringAlloc(REFPROPVARIANT propvar, __out PWSTR *ppszOut);   // VT_LPWSTR or VT_BSTR
PSSTDAPI
PropVariantToStringVector(REFPROPVARIANT propvar, __out_ecount_part(crgsz, *pcElem) PWSTR *prgsz, ULONG crgsz, __out ULONG *pcElem);   // VT_VECTOR | VT_LPWSTR
PSSTDAPI
PropVariantToStringVectorAlloc(REFPROPVARIANT propvar, __out_ecount(*pcElem) PWSTR **pprgsz, __out ULONG *pcElem);   // VT_VECTOR | VT_LPWSTR

// Other
PSSTDAPI PropVariantToGUID(REFPROPVARIANT propvar, __out GUID *pguid);         // VT_GUID
PSSTDAPI
PropVariantToStrRet(REFPROPVARIANT propvar, __out STRRET *pstrret);   // VT_LPWSTR or VT_BSTR
PSSTDAPI
PropVariantToFileTime(REFPROPVARIANT propvar, PSTIME_FLAGS pstfOut, __out FILETIME* pftOut);   // VT_FILETIME
HRESULT
PropVariantToCLSID(REFPROPVARIANT propvar, __out CLSID *pclsid);       // VT_GUID

I briefly want to mention that if given a vector, PropVariantToString() will return a semicolon delimited string.  This is different behavior than PropVariantChangeType().

Most of these helpers are declared in propvarutil.h and implemented in propsys.dll.