IUrlHistoryStg2 :: ClearHistory () не работает из службы? - PullRequest
0 голосов
/ 29 ноября 2010

Метод IUrlHistoryStg2 :: ClearHistory () документирован как пользовательский.

http://msdn.microsoft.com/en-us/library/aa767715(VS.85).aspx

При вызове из службы, работающей под учетной записью SYSTEM, я не могу настроить таргетинг на определенных пользователей, вошедших в систему. Я успешно выдал себя за пользователя с помощью WindowsIdentity.Impersonate (), но вызов ClearHistory () всегда возвращает 0 для успеха, но не очищает историю пользователя.

Это применимо как к XP, так и к Win7, поэтому, похоже, это не проблема изоляции сеанса.

Возможно, потому что это COM, что-то смотрит на токен процесса вызывающей стороны, а не на его токен потока при олицетворении?

Я смущен, почему выдавая себя за пользователя не просто приводит к успеху этого метода?

using System;
using System.Runtime.InteropServices;

/**
* wrapper for IUrlHistory
*/
public struct STATURL
{
    public static uint SIZEOF_STATURL = (uint)Marshal.SizeOf( typeof(STATURL) );
    public uint cbSize;
    [MarshalAs(UnmanagedType.LPWStr)] public string pwcsUrl;
    [MarshalAs(UnmanagedType.LPWStr)] public string pwcsTitle;
    public System.Runtime.InteropServices.ComTypes.FILETIME
                ftLastVisited,
                ftLastUpdated,
                ftExpires;
    public uint dwFlags;
}

[ComImport, Guid("3C374A42-BAE4-11CF-BF7D-00AA006946EE"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumSTATURL
{
    [PreserveSig]
    uint Next(uint celt, out STATURL rgelt, out uint pceltFetched);
    void Skip(uint celt);
    void Reset();
    void Clone(out IEnumSTATURL ppenum);
    void SetFilter(
        [MarshalAs(UnmanagedType.LPWStr)] string poszFilter,
        uint dwFlags);
}

[ComImport, Guid("AFA0DC11-C313-11d0-831A-00C04FD5AE38"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IUrlHistoryStg2
{
    #region IUrlHistoryStg methods
    void AddUrl(
        [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl,
        [MarshalAs(UnmanagedType.LPWStr)] string pocsTitle,
        uint dwFlags);

    void DeleteUrl(
        [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl,
        uint dwFlags);

    void QueryUrl(
        [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl,
        uint dwFlags,
        ref STATURL lpSTATURL);

    void BindToObject(
        [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl,
        ref Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppvOut);

    IEnumSTATURL EnumUrls();

    #endregion

    void AddUrlAndNotify(
        [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl,
        [MarshalAs(UnmanagedType.LPWStr)] string pocsTitle,
        uint dwFlags,
        [MarshalAs(UnmanagedType.Bool)] bool fWriteHistory,
        [MarshalAs(UnmanagedType.IUnknown)] object /*IOleCommandTarget*/
        poctNotify,
        [MarshalAs(UnmanagedType.IUnknown)] object punkISFolder);

    void ClearHistory();
}

[ComImport, Guid("3C374A40-BAE4-11CF-BF7D-00AA006946EE")]
public class UrlHistory /* : IUrlHistoryStg[2] */ {}


public class test
{
    static void Main()
    {
        IUrlHistoryStg2 stg = (IUrlHistoryStg2) new UrlHistory();
        stg.ClearHistory();
    }
}

Ответы [ 2 ]

2 голосов
/ 29 ноября 2010

Если служба или приложение олицетворяет пользователя, система не загружает профиль пользователя.Попробуйте сначала вызвать LoadUserProfile .

1 голос
/ 19 апреля 2016

IUrlHistoryStg2 в конечном итоге использует такие API-интерфейсы Wininet, как CommitUrlCacheEntryW

В документации Microsoft говорится, что:

Как и все другие аспектыWinINet API, эта функция не может быть безопасно вызвана из DllMain или конструкторов и деструкторов глобальных объектов.Примечание. WinINet не поддерживает серверные реализации.Кроме того, он не должен использоваться из службы.Для серверных реализаций или служб используйте Microsoft Windows HTTP Services (WinHTTP).

Я отменил эти API и обнаружил, что у них есть проверка для

  • Олицетворение
  • Запуск из службы

Если любой из них равен true, API существует с кодом ошибки 0x80070078

Так что, к счастью, то, что вы пытаетесь достичь, невозможно из службы, и вы должныиспользуйте CreateProcessAsUser

...