Re: .NET and IE Favourites



Thanks Bill,

It seems obvious that the readmultiple values must be arrays, but I can
only get the code to work only if they are not arrays...

I've posted the new code below, but now only PID_IS URL works: the rest
of the metadata can't be read (possibly because I've changed them from
arrays...). I've added a utility called PrintUrlMetadata that loops
through the valid values.

Thanks for the link, but I'm interested in the url object metadata, not
the dir hierarchy of the favorites. I know that some of the values can
either be taken from the .url shortcut (date created etc), and from
parsing the shortcut file but this won't gve me all the metadata I
need...

Any further ideas?

Many Thanks,

Paul


----------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace TestIE
{
using System;
using System.Runtime.InteropServices;

[ComImport, Guid("CABB0DA0-DA57-11CF-9974-0020AFD79762"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUniformresourceLocatorW{}

[ComImport, Guid("FBF23B40-E3F0-101B-8488-00AA003E56F8")]
class InternetShortcut : IUniformresourceLocatorW{}

public enum FMTID_Intshcut : int
{
PID_IS_URL = 2,
PID_IS_NAME = 4,
PID_IS_WORKINGDIR = 5,
PID_IS_HOTKEY = 6,
PID_IS_SHOWCMD = 7,
PID_IS_ICONINDEX = 8,
PID_IS_ICONFILE = 9,
PID_IS_WHATSNEW = 10,
PID_IS_AUTHOR = 11,
PID_IS_DESCRIPTION = 12,
PID_IS_COMMENT = 13
}

public enum FMTID_InternetSite : int
{
PID_INTSITE_WHATSNEW = 2,
PID_INTSITE_AUTHOR = 3,
PID_INTSITE_LASTVISIT = 4,
PID_INTSITE_LASTMOD = 5,
PID_INTSITE_VISITCOUNT = 6,
PID_INTSITE_DESCRIPTION = 7,
PID_INTSITE_COMMENT = 8,
PID_INTSITE_FLAGS = 9,
PID_INTSITE_CONTENTLEN = 10,
PID_INTSITE_CONTENTCODE = 11,
PID_INTSITE_RECURSE = 12,
PID_INTSITE_WATCH = 13,
PID_INTSITE_SUBSCRIPTION = 14,
PID_INTSITE_URL = 15,
PID_INTSITE_TITLE = 16,
PID_INTSITE_CODEPAGE = 18,
PID_INTSITE_TRACKING = 19
}

public enum STGM : int
{
READ = 0x00000000,
WRITE = 0x00000001,
READWRITE = 0x00000002,
SHARE_DENY_NONE = 0x00000040,
SHARE_DENY_READ = 0x00000030,
SHARE_DENY_WRITE = 0x00000020,
SHARE_EXCLUSIVE = 0x00000010,
PRIORITY = 0x00040000,
CREATE = 0x00001000,
CONVERT = 0x00020000,
FAILIFTHERE = 0x00000000,
DIRECT = 0x00000000,
TRANSACTED = 0x00010000,
NOSCRATCH = 0x00100000,
NOSNAPSHOT = 0x00200000,
SIMPLE = 0x08000000,
DIRECT_SWMR = 0x00400000,
DELETEONRELEASE = 0x04000000
}

class TestShortcut
{
[STAThread]
static void Main()
{
// Change to known path:
string urlPath = @"C:\Documents and
Settings\quinnp\Favorites\Links\Mail.url";

Guid FMTID_Intshcut_Guid = new Guid("{0x000214A0, 0x0000,
0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}");

IPersistFile ieShortCut = new InternetShortcut() as
IPersistFile;

// ...reads true
Console.WriteLine(ieShortCut != null);

ieShortCut.Load(urlPath, (int)STGM.READWRITE);

// Test to see if COM object was correctly loaded:
IntPtr filePtr = IntPtr.Zero;
string file = string.Empty;
ieShortCut.GetCurFile(out filePtr);
Debug.WriteLine(Marshal.PtrToStringUni(filePtr));
//...should be ok

IPropertySetStorage shortCutPropStorage = ieShortCut as
IPropertySetStorage;
IPropertyStorage propertyStorage = null;

shortCutPropStorage.Open(ref FMTID_Intshcut_Guid,
(int)(STGM.READWRITE | STGM.SHARE_EXCLUSIVE), ref propertyStorage);

PropSpec specs = new PropSpec();
specs.ulKind = 1;
specs.Name_Or_ID = (IntPtr)FMTID_Intshcut.PID_IS_URL;
PropVariant vars = new PropVariant();

int hr = propertyStorage.ReadMultiple(1, ref specs, out
vars);
if (hr == 0)
{
// Works now...
Debug.WriteLine("URL:" +
Marshal.PtrToStringAuto(vars.pointerValue));
//ole32.PropVariantClear(ref vars[0]);
}

// Attempt to print the rest of the metadata:
PrintUrlMetadata(propertyStorage);
}

public static void PrintUrlMetadata(IPropertyStorage
metaDataStore)
{
int[] valueArray =
(int[])Enum.GetValues(typeof(FMTID_Intshcut));
PropSpec specs = new PropSpec();
PropVariant vars = new PropVariant();

foreach(int val in valueArray)
{
specs.ulKind = 1;
specs.Name_Or_ID = (IntPtr)val;

int hr = metaDataStore.ReadMultiple(1, ref specs, out
vars);
if (hr == 0)
{
string currentVal =
Enum.GetName(typeof(FMTID_Intshcut),val);
Debug.WriteLine(currentVal + " " +
Marshal.PtrToStringAuto(vars.pointerValue));
}
}
}
}

[ComVisible(true), ComImport(),
Guid("0000013A-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertySetStorage
{
uint Create(
ref System.Guid rfmtid,
IntPtr pclsid,
int grfFlags,
int grfMode,
ref IPropertyStorage propertyStorage);

int Open(
ref System.Guid rfmtid,
int grfMode,
ref IPropertyStorage propertyStorage);
}

[ComVisible(true), ComImport(),
Guid("00000138-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyStorage
{
[PreserveSig]
int ReadMultiple(
uint numProperties,
ref PropSpec propertySpecifications,
out PropVariant propertyValues);

int WriteMultiple(
uint numProperties,
[MarshalAs(UnmanagedType.Struct)] ref PropSpec
propertySpecification,
ref PropVariant propertyValues,
int propIDNameFirst);

uint Commit(
int commitFlags);
}

[StructLayout(LayoutKind.Explicit, Size = 8, CharSet =
CharSet.Unicode)]
public struct PropSpec
{
[FieldOffset(0)]
public int ulKind;
[FieldOffset(4)]
public IntPtr Name_Or_ID;
}

[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PropVariant
{
[FieldOffset(0)]
public short variantType;
[FieldOffset(8)]
public IntPtr pointerValue;
[FieldOffset(8)]
public byte byteValue;
[FieldOffset(8)]
public long longValue;

public void FromObject(object obj)
{
if (obj.GetType() == typeof(string))
{
this.variantType = (short)VarEnum.VT_LPWSTR;
this.pointerValue =
Marshal.StringToHGlobalUni((string)obj);
}
}
}

[ComImport, Guid("0000010B-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistFile
{
void GetClassID(out Guid pClassID);
[PreserveSig]
int IsDirty();
void Load([MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
int
dwMode);
void Save([MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
[MarshalAs(UnmanagedType.Bool)] bool fRemember);
void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] string
pszFileName);
void GetCurFile(out IntPtr ppszFileName);
}
}

.



Relevant Pages

  • Re: WMEncoder
    ... public Guid majortype; ... int GetLength( ... void GetStreamNumber( ... ref int pcchStreamName); ...
    (microsoft.public.windowsmedia.sdk)
  • ExecutionEngineException trying to override IInternetSecurityManager
    ... public void QueryService(ref Guid guidService, ref Guid riid, out object ... void SaveObject; ... int GetSecuritySite; ... out UInt32 pdwZone, UInt32 dwFlags); ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: Difference between out and ref parameters.
    ... you don't have to initialize an "out" parameter before passing it to a method ... int x = 0; ... void add ... > 'ref' parameter passes the object into the Method by Reference, ...
    (microsoft.public.dotnet.general)
  • .NET and IE Favourites
    ... public enum STGM: int ... , ref propertyStorage); ... ref System.Guid rfmtid, ... public void FromObject ...
    (microsoft.public.dotnet.framework.interop)
  • Re: Help With PInvoke and SetupDiEnumDriverInfo/SP_DRVINFO_DATA
    ... public const int DIGCF_PRESENT =; ... public static extern IntPtr SetupDiGetClassDevs(ref Guid ... ref SP_DEVINFO_DATA DeviceInfoData); ... ref SP_DEVINFO_DATA DeviceInfoData, int Property, ref int ...
    (microsoft.public.dotnet.languages.csharp)