小弟在调用API (DsBrowseForContainer)的时候 当多次调用时就出现
System.AccessViolationException: Attempted to read or write protected memory. 得异常[DllImport("dsuiext.dll", CharSet = CharSet.Unicode)]
public static extern int DsBrowseForContainer(ref DSBrowseInfo info);我在调用前将info声明为静态变量,但多次调用仍然出现此异常。各位大虾可否帮帮小弟 能给小弟个例子谢谢了。code:abstract class NativeMethods
    {
        /// <summary>
        /// The DsBrowseForContainer function sets up and displays a simple dialog box
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [DllImport("dsuiext.dll", CharSet = CharSet.Unicode)]
        public static extern int DsBrowseForContainer( [In, Out] ref Utils.DSBrowseInfo info);
    }    internal static class Utils
    {
        /// <summary>
        /// BFFCallBack
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="uMsg"></param>
        /// <param name="lParam"></param>
        /// <param name="lpData"></param>
        /// <returns></returns>
        public delegate int BFFCallBack(IntPtr hwnd, uint uMsg, int lParam, int lpData);        /// <summary>
        /// The DsBrowseForContainer function sets up and displays a simple dialog box
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct DSBrowseInfo// : IDisposable
        {
            /// <summary>
            /// size of structure in bytes
            /// </summary>
            public int cbStruct;            /// <summary>
            /// dialog owner
            /// </summary>
            public IntPtr hwndOwner;            /// <summary>
            /// dialog caption text (can be NULL)
            /// </summary>
            [MarshalAs(UnmanagedType.LPTStr, SizeConst = 32)]
            public string pszCaption;            /// <summary>
            /// displayed above the tree view control (can be NULL)
            /// </summary>
            [MarshalAs(UnmanagedType.LPTStr, SizeConst = 32)]
            public string pszTitle;            /// <summary>
            /// ADS path to root (NULL == root of DS namespace)
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr, SizeConst = 32)]
            public string pszRoot;            /// <summary>
            /// [in/out] initial selection and returned path (required)
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr, SizeConst = 32)]
            public string pszPath;            /// <summary>
            /// size of pszPath buffer in characters
            /// </summary>
            public int cchPath;            /// <summary>
            /// Flags
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwFlags;            /// <summary>
            /// callback function (see SHBrowseForFolder)
            /// </summary>
            [MarshalAs ( UnmanagedType.FunctionPtr)]
            public BFFCallBack pfnCallback;            /// <summary>
            /// passed to pfnCallback as lpUserData
            /// </summary>
            public object lParam;            /// <summary>
            /// ADS_FORMAT_* (default is ADS_FORMAT_X500_NO_SERVER)
            /// </summary>
            public int dwReturnFormat;            /// <summary>
            /// Username to authenticate against DS with
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr, SizeConst = 32)]
            public string pUserName;            /// <summary>
            /// Password to authenticate against DS with
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr, SizeConst = 32)]
            public string pPassword;            /// <summary>
            /// NICODE string for the object class
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr, SizeConst = 32)]
            public string pszObjectClass;            /// <summary>
            /// NICODE string for the object class
            /// </summary>
            public long cchObjectClass;            ///// <summary>
            ///// Dispose of DSBrowseInfo
            ///// </summary>
            //public void Dispose()
            //{
            //    GC.SuppressFinalize(this);
            //}
        }
        /// <summary>
        /// DSBrowseInfoFlags
        /// </summary>
        public enum DSBrowseInfoFlag : int
        {
            /// <summary>
            /// don't include pszRoot in tree (its children become top level nodes)
            /// </summary>
            NoRoot = 0x00010000,            /// <summary>
            /// ignore the treat as leaf flag when calling IsClassContainer
            /// </summary>
            Root = 0x00400000,
        }

解决方案 »

  1.   

    /// <summary>
            /// The DsBrowseForContainer function sets up and displays a simple dialog box.
            /// </summary>
            /// <param name="root"></param>
            /// <param name="result"></param>
            /// <param name="flags"></param>
            /// <param name="hwndOwner"></param>
            /// <param name="MessageInfo"></param>
            /// <returns></returns>
            public static bool PickContainer(string root, ref string result, int flags, IntPtr hwndOwner, ref string MessageInfo)
            {
                DSBrowseInfo dsbi = new DSBrowseInfo();            dsbi.cbStruct = 60;
                dsbi.hwndOwner = hwndOwner; //call Handle of class
                dsbi.pszCaption = Properties.Resources.SelectNewContainerCaption;
                dsbi.pszTitle = Properties.Resources.SelectNewContainerTitle;
                dsbi.pszRoot = root;    //root:null
                dsbi.pszPath = result;    //result:""
                dsbi.cchPath = 1040;
                dsbi.dwFlags = flags;    //4259840
                dsbi.pfnCallback = null;
                dsbi.lParam = 0;            int IdOk = 1;
                int IdCancel = 2;            try
                {
                    int returnValue = NativeMethods.DsBrowseForContainer(ref dsbi);                if (returnValue.Equals(IdOk))
                    {
                        result = dsbi.pszPath;
                        return true;
                    }
                    else if (!returnValue.Equals(IdCancel))
                    {
                        if (dsbi.pszRoot == null)
                        {
                            dsbi.pszRoot = "LDAP:";
                        }                    // try 5 times max.
                        for (int i = 0; i < 5; i++)
                        {
                            returnValue = NativeMethods.DsBrowseForContainer(ref dsbi);
                            if (returnValue.Equals(IdOk) || returnValue.Equals(IdCancel))
                                break;
                        }                    if (returnValue.Equals(IdOk))
                        {
                            return true;
                        }
                        else if (!returnValue.Equals(IdCancel))
                        {
                            string csRoot = String.Empty;
                            if (dsbi.pszRoot != null)
                            {
                                csRoot = dsbi.pszRoot;
                            }                        MessageInfo = String.Format(CultureInfo.InvariantCulture, "{0}\n\n{1} {2}\n\n{3}",
                                                            Properties.Resources.NCMessageInfoOne,
                                                            Properties.Resources.NCMessageInfoTwo,
                                                            csRoot,
                                                            Properties.Resources.NCMessageInfoThree);
                            return false;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (System.Security.SecurityException ex)
                {
                    Trace.TraceInformation(ex.ToString());
                    return false;
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                    MessageInfo = ex.ToString();
                    return false;
                }
                finally
                {
                    //dsbi.Dispose();
                    //GC.Collect();
                }
            }