// Show the find dialog do locate the assemblies. // private void browseButton_Click(object sender, EventArgs e) { IVsUIShell uis = (IVsUIShell)parentPage.GetService(typeof(IVsUIShell)); if (uis != null) { int buffSize = 512; IntPtr buffPtr = IntPtr.Zero; _VSOPENFILENAMEW ofn = new _VSOPENFILENAMEW(); try { char[] buffer = new char[buffSize]; buffPtr = Marshal.AllocCoTaskMem(buffer.Length * 2); Marshal.Copy(buffer, 0, buffPtr, buffer.Length); ofn.lStructSize = Marshal.SizeOf(typeof(_VSOPENFILENAMEW)); ofn.hwndOwner = Handle; ofn.pwzFilter = MakeFilterString(SR.GetString(SR.AddRemoveComponentsFilter)); ofn.pwzFileName = buffPtr; ofn.nMaxFileName = buffSize; if (uis.GetOpenFileNameViaDlg(ref ofn) == NativeMethods.S_OK) { Marshal.Copy(buffPtr, buffer, 0, buffer.Length); int i = 0; while (i < buffer.Length && buffer[i] != 0) { i++; } string fileName = new string(buffer, 0, i); AddItems(fileName); } } finally { if (buffPtr != IntPtr.Zero) { Marshal.FreeCoTaskMem(buffPtr); } } } else { if (openFileDialog.ShowDialog() == DialogResult.OK) { AddItems(openFileDialog.FileName); } controlList.Focus(); } }
public string BrowseForFileOpen(IntPtr owner, string filter, string initialPath = null, string title = null) { IVsUIShell uiShell = VsAppShell.Current.GetGlobalService <IVsUIShell>(typeof(SVsUIShell)); if (uiShell == null) { return(null); } if (owner == IntPtr.Zero) { ErrorHandler.ThrowOnFailure(uiShell.GetDialogOwnerHwnd(out owner)); } VSOPENFILENAMEW[] openInfo = new VSOPENFILENAMEW[1]; openInfo[0].lStructSize = (uint)Marshal.SizeOf(typeof(VSOPENFILENAMEW)); openInfo[0].pwzFilter = filter.Replace('|', '\0') + "\0"; openInfo[0].hwndOwner = owner; openInfo[0].pwzDlgTitle = title; openInfo[0].nMaxFileName = 260; var pFileName = Marshal.AllocCoTaskMem(520); openInfo[0].pwzFileName = pFileName; openInfo[0].pwzInitialDir = Path.GetDirectoryName(initialPath); var nameArray = (Path.GetFileName(initialPath) + "\0").ToCharArray(); Marshal.Copy(nameArray, 0, pFileName, nameArray.Length); try { int hr = uiShell.GetOpenFileNameViaDlg(openInfo); if (hr == VSConstants.OLE_E_PROMPTSAVECANCELLED) { return(null); } ErrorHandler.ThrowOnFailure(hr); return(Marshal.PtrToStringAuto(openInfo[0].pwzFileName)); } finally { if (pFileName != IntPtr.Zero) { Marshal.FreeCoTaskMem(pFileName); } } }
public static string BrowseForFileOpen(this IServiceProvider serviceProvider, IntPtr owner, string filter, string initialPath = null) { if (string.IsNullOrEmpty(initialPath)) { initialPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + Path.DirectorySeparatorChar; } IVsUIShell uiShell = serviceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if (null == uiShell) { using (var sfd = new System.Windows.Forms.OpenFileDialog()) { sfd.AutoUpgradeEnabled = true; sfd.Filter = filter; sfd.FileName = Path.GetFileName(initialPath); sfd.InitialDirectory = Path.GetDirectoryName(initialPath); DialogResult result; if (owner == IntPtr.Zero) { result = sfd.ShowDialog(); } else { result = sfd.ShowDialog(NativeWindow.FromHandle(owner)); } if (result == DialogResult.OK) { return(sfd.FileName); } else { return(null); } } } if (owner == IntPtr.Zero) { ErrorHandler.ThrowOnFailure(uiShell.GetDialogOwnerHwnd(out owner)); } VSOPENFILENAMEW[] openInfo = new VSOPENFILENAMEW[1]; openInfo[0].lStructSize = (uint)Marshal.SizeOf(typeof(VSOPENFILENAMEW)); openInfo[0].pwzFilter = filter.Replace('|', '\0') + "\0"; openInfo[0].hwndOwner = owner; openInfo[0].nMaxFileName = 260; var pFileName = Marshal.AllocCoTaskMem(520); openInfo[0].pwzFileName = pFileName; openInfo[0].pwzInitialDir = Path.GetDirectoryName(initialPath); var nameArray = (Path.GetFileName(initialPath) + "\0").ToCharArray(); Marshal.Copy(nameArray, 0, pFileName, nameArray.Length); try { int hr = uiShell.GetOpenFileNameViaDlg(openInfo); if (hr == VSConstants.OLE_E_PROMPTSAVECANCELLED) { return(null); } ErrorHandler.ThrowOnFailure(hr); return(Marshal.PtrToStringAuto(openInfo[0].pwzFileName)); } finally { if (pFileName != IntPtr.Zero) { Marshal.FreeCoTaskMem(pFileName); } } }
/// <summary> /// Shows the Visual Studio open file dialog. /// </summary> /// <param name="dialogTitle">The title for the dialog box.</param> /// <param name="filter">The filter for the dialog.</param> /// <param name="initialDirectory">The initial starting directory. Can be null to use the current directory.</param> /// <returns>An array of paths to the chosen files or an empty array if the user canceled the dialog.</returns> public string[] ShowOpenFileDialog(string dialogTitle, string filter, string initialDirectory) { ArrayList fileNames = new ArrayList(); int bufferSize = NativeMethods.MAX_PATH; // Get the HWND to use for the modal file dialog. IntPtr hwnd; IVsUIShell uiShell = this.ServiceProvider.GetVsUIShell(classType, "ShowOpenFileDialog"); NativeMethods.ThrowOnFailure(uiShell.GetDialogOwnerHwnd(out hwnd)); // Create a native string buffer for the file name. IntPtr pwzFileName = Marshal.StringToHGlobalUni(new string('\0', bufferSize)); try { // Fill in open file options structure. VSOPENFILENAMEW[] openFileOptions = new VSOPENFILENAMEW[1]; openFileOptions[0].lStructSize = (uint)Marshal.SizeOf(typeof(VSOPENFILENAMEW)); openFileOptions[0].hwndOwner = hwnd; openFileOptions[0].pwzDlgTitle = dialogTitle; openFileOptions[0].pwzFileName = pwzFileName; openFileOptions[0].nMaxFileName = (uint)bufferSize; openFileOptions[0].pwzFilter = filter; openFileOptions[0].pwzInitialDir = initialDirectory; openFileOptions[0].dwFlags = (uint)(VsOpenFileDialogFlags.AllowMultiSelect); // Open the Visual Studio open dialog. int hr = uiShell.GetOpenFileNameViaDlg(openFileOptions); bool canceled = (hr == NativeMethods.OLE_E_PROMPTSAVECANCELLED); if (NativeMethods.Failed(hr) && !canceled) { NativeMethods.ThrowOnFailure(hr); } // Get the file name(s). if (openFileOptions[0].pwzFileName != IntPtr.Zero && !canceled) { // We want to get the entire buffered string because if multiple files were selected then it has // the following format: directory\0file1\0file2\0...fileN\0\0. Note that it ends with two null // terminators. string rawDialogPath = Marshal.PtrToStringUni(openFileOptions[0].pwzFileName, bufferSize); // These will hold our currently parsed values. StringBuilder directory = new StringBuilder(); StringBuilder fileName = new StringBuilder(); bool parsingDirectory = true; // Walk over the raw string to pull out the directory and the file names. for (int i = 0; i < rawDialogPath.Length; i++) { char c = rawDialogPath[i]; char nextC = (i + 1 < rawDialogPath.Length ? rawDialogPath[i + 1] : '\0'); // If we've hit a null termination, then we have to stop parsing for a second and add an // item to our array. if (c != '\0') { if (parsingDirectory) { directory.Append(c); } else { fileName.Append(c); } } else { if (parsingDirectory) { parsingDirectory = false; } else { // We've seen another file, so let's add the absolute path to our array. string absolutePath = Path.Combine(directory.ToString(), fileName.ToString()); absolutePath = PackageUtility.CanonicalizeFilePath(absolutePath); fileNames.Add(absolutePath); // Clear the file name StringBuilder for the next round. fileName.Length = 0; } // If we are at the double null termination then we can quit parsing. if (nextC == '\0') { // If the user only selected one file, then our parsed directory should be the full file name. if (fileNames.Count == 0) { fileNames.Add(directory.ToString()); } break; } } } } } finally { // Release the string buffer. if (pwzFileName != IntPtr.Zero) { Marshal.FreeHGlobal(pwzFileName); } } return((string[])fileNames.ToArray(typeof(string))); }