Как запретить автозапуск и запустить собственное приложение при подключении USB-накопителя

при вставке USB-флеш-накопителя Windows обычно открывает диалоговое окно «Автозапуск», в котором предлагается просмотреть диск или, если есть мультимедийные файлы, выбрать приложение для их открытия.

Мы разработали медиаплеер, который подключается к USB-накопителю и регистрируется как Mass Storage Device.

Мне нужно, чтобы при вставке плеера этот диалог не показывался, а вместо этого запускалось мое собственное приложение.

В идеале приложение должно быть на самой флешке, но как я понял автозапуск отключен для USB-накопителей.

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

Лучший Том


person Thomas    schedule 31.05.2012    source источник
comment
Конечно, это невозможно, это относится к категории того, что, если все будут так делать?   -  person Hans Passant    schedule 31.05.2012
comment
нашел два решения для реагирования на вставки дисков, которые предотвращают диалоговое окно автозапуска и работают, даже если нет самого верхнего окна: C++: codeproject.com/Articles/14500/ c#: codeproject.com/Articles/18062/ dotnet247.com/247reference/msgs/32/164968.aspx   -  person Thomas    schedule 31.05.2012


Ответы (2)


после долгих исследований в Google я нашел это сообщение на форуме:

http://social.msdn.microsoft.com/Forums/uk-UA/windowssdk/thread/aef929cb-62ac-4371-b7de-2c07adf3c6a7

Я последовал этому, и вот рабочий код:

[Flags()]
public enum AutorunContent : int
{
    AutorunInf = 2,
    AudioCD = 4,
    DVDMovie = 8,
    BlankCD = 16,
    BlankDVD = 32,
    UnknownContent = 64,
    AutoPlayPictures = 128,
    AutoPlayMusics = 256,
    AutoPlayMovies = 512
}


[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("DDEFE873-6997-4e68-BE26-39B633ADBE12")]
public interface IQueryCancelAutoPlay
{
    [PreserveSig]
    int AllowAutoPlay(
      [MarshalAs(UnmanagedType.LPWStr)] string pszPath,
      [MarshalAs(UnmanagedType.U4)] AutorunContent dwContentType,
      [MarshalAs(UnmanagedType.LPWStr)] string pszLabel,
      [MarshalAs(UnmanagedType.U4)] int dwSerialNumber);
}


public class RunningObjectTableEntry : IDisposable
{
    private int cookie;
    private IRunningObjectTable rot = null;
    private IMoniker monkey = null;

    private RunningObjectTableEntry() { }

    /// <summary>
    /// Creates a new entry for the given object
    /// </summary>
    /// <param name="obj">Object to make an entry for. Only one object per class should ever be registered.</param>
    public RunningObjectTableEntry(object obj)
    {
        int hr = GetRunningObjectTable(0, out rot);
        if (hr != 0)
        {
            throw new COMException("Could not retreive running object table!", hr);
        }

        Guid clsid = obj.GetType().GUID;
        hr = CreateClassMoniker(ref clsid, out monkey);
        if (hr != 0)
        {
            Marshal.ReleaseComObject(rot);
            throw new COMException("Could not create moniker for CLSID/IID \"" + clsid + "\"!", hr);
        }

        cookie = rot.Register(0x01, obj, monkey);   //weak reference, but allow any user
    }

    [DllImport("ole32.dll", ExactSpelling = true)]
    private static extern int GetRunningObjectTable([MarshalAs(UnmanagedType.U4)] int reserved, out IRunningObjectTable pprot);

    [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    private static extern int CreateClassMoniker([In] ref Guid g, [Out] out IMoniker ppmk);

    #region IDisposable Members

    /// <summary>
    /// De-registers the object and class from the Running Object Table
    /// </summary>
    public void Dispose()
    {
        Marshal.ReleaseComObject(monkey);
        rot.Revoke(cookie);
        Marshal.ReleaseComObject(rot);
    }

    #endregion
}



[ComVisible(true)]
[Guid("331F1768-05A9-4ddd-B86E-DAE34DDC998A")]
[ClassInterface(ClassInterfaceType.None)]
public class Autoplay : IQueryCancelAutoPlay, IDisposable
{
    private RunningObjectTableEntry rotEntry;

    public Autoplay()
    {
        rotEntry = new RunningObjectTableEntry(this);
    }

    #region IQueryCancelAutoPlay Members

    public int AllowAutoPlay(string pszPath, AutorunContent dwContentType, string pszLabel, int dwSerialNumber)
    {
        if (pszLabel == "FUNKEYPLAY")  //This is the name of my volume that should not call autoplay
        {


            return 1;
        }
        else
        {
            return 0;
        }
        //Console.WriteLine("QueryCancelAutoPlay:");
        //Console.WriteLine("   " + pszPath);
        //Console.WriteLine("   " + dwContentType.ToString("x"));
        //Console.WriteLine("   " + pszLabel);
        //Console.WriteLine("   " + dwSerialNumber.ToString());
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        rotEntry.Dispose();
    }

    #endregion
}

}

person Thomas    schedule 28.08.2012

Попробуйте посмотреть все файлы с вашего USB. В настройках папки вы можете выбрать отображение/скрытие скрытых файлов. На вашем устройстве есть файл с именем autorun.inf, который применяется каждый раз, когда вы вставляете USB-накопитель. Поэтому, если вы откроете файл и наберете имя приложения, оно будет запускаться автоматически каждый раз, когда вы вставляете флэш-память.

person Community    schedule 31.05.2012