Need a dialog box to browse computers on a network
The FolderBrowserDialog
does allow me to browse computers on the network, but it displays other unnecessary folders (I don't want local 开发者_运维知识库folders). Also, I don't want to have to select a folder - just the computer name.
Simple:
private void button1_Click(object sender, EventArgs e)
{
var folderName = GetNetworkFolders(new FolderBrowserDialog());
}
private string GetNetworkFolders(FolderBrowserDialog oFolderBrowserDialog)
{
Type type = oFolderBrowserDialog.GetType();
FieldInfo fieldInfo = type.GetField("rootFolder", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(oFolderBrowserDialog, 18);
if (oFolderBrowserDialog.ShowDialog() == DialogResult.OK)
{
return oFolderBrowserDialog.SelectedPath.ToString();
}
else
{
return "";
}
}
ComputerBrowser.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class ComputerBrowser
{
private FolderBrowserFolder _startLocation = FolderBrowserFolder.NetworkNeighborhood;
private BrowseInfos _options = BrowseInfos.BrowseForComputer;
private static readonly int MAX_PATH;
private string _title;
private string _displayName;
private string _path;
static ComputerBrowser()
{
MAX_PATH = 260;
}
public bool ShowDialog()
{
return ShowDialog(null);
}
public bool ShowDialog(IWin32Window owner)
{
_path = string.Empty;
IntPtr handle;
IntPtr zero = IntPtr.Zero;
if (owner != null)
handle = owner.Handle;
else
handle = UnmanagedMethods.GetActiveWindow();
UnmanagedMethods.SHGetSpecialFolderLocation(handle, (int)_startLocation, ref zero);
if (zero == IntPtr.Zero)
return false;
int num = (int)_options;
if ((num & 0x40) != 0)
Application.OleRequired();
IntPtr pidl = IntPtr.Zero;
try
{
BrowseInfo lpbi = new BrowseInfo();
//IntPtr pszPath = Marshal.AllocHGlobal(MAX_PATH);
lpbi.pidlRoot = zero;
lpbi.hwndOwner = handle;
lpbi.displayName = new string('\0', MAX_PATH);
lpbi.title = _title;
lpbi.flags = num;
lpbi.callback = null;
lpbi.lparam = IntPtr.Zero;
pidl = UnmanagedMethods.SHBrowseForFolder(ref lpbi);
if (pidl == IntPtr.Zero)
return false;
_displayName = lpbi.displayName;
StringBuilder pathReturned = new StringBuilder(MAX_PATH);
UnmanagedMethods.SHGetPathFromIDList(pidl, pathReturned);
_path = pathReturned.ToString();
UnmanagedMethods.SHMemFree(pidl);
}
finally
{
UnmanagedMethods.SHMemFree(zero);
}
return true;
}
protected enum FolderBrowserFolder
{
Desktop = 0,
Favorites = 6,
MyComputer = 0x11,
MyDocuments = 5,
MyPictures = 0x27,
NetAndDialUpConnections = 0x31,
NetworkNeighborhood = 0x12,
Printers = 4,
Recent = 8,
SendTo = 9,
StartMenu = 11,
Templates = 0x15
}
[Flags]
public enum BrowseInfos
{
AllowUrls = 0x80,
BrowseForComputer = 0x1000,
BrowseForEverything = 0x4000,
BrowseForPrinter = 0x2000,
DontGoBelowDomain = 2,
ShowTextBox = 0x10,
NewDialogStyle = 0x40,
RestrictToSubfolders = 8,
RestrictToFilesystem = 1,
ShowShares = 0x8000,
StatusText = 4,
UseNewUI = 80,
Validate = 0x20
}
public static string GetComputerName(string title)
{
ComputerBrowser browser = new ComputerBrowser();
browser._title = title;
if (browser.ShowDialog())
return browser._displayName;
else
return string.Empty;
}
}
Unmanaged.cs:
using System;
using System.Runtime.InteropServices;
namespace ActivityMonitor.Monitor.Utils
{
internal delegate int BrowseCallBackProc(IntPtr hwnd, int msg, IntPtr lp, IntPtr wp);
[StructLayout(LayoutKind.Sequential)]
internal struct BrowseInfo
{
public IntPtr hwndOwner;
public IntPtr pidlRoot;
[MarshalAs(UnmanagedType.LPTStr)]
public string displayName;
[MarshalAs(UnmanagedType.LPTStr)]
public string title;
public int flags;
[MarshalAs(UnmanagedType.FunctionPtr)]
public BrowseCallBackProc callback;
public IntPtr lparam;
}
[ComImport]
[Guid("00000002-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMalloc
{
[PreserveSig]
IntPtr Alloc(IntPtr cb);
[PreserveSig]
IntPtr Realloc(IntPtr pv, IntPtr cb);
[PreserveSig]
void Free(IntPtr pv);
[PreserveSig]
IntPtr GetSize(IntPtr pv);
[PreserveSig]
int DidAlloc(IntPtr pv);
[PreserveSig]
void HeapMinimize();
}
/// <summary>
/// A class that defines all the unmanaged methods used in the assembly
/// </summary>
internal class UnmanagedMethods
{
[DllImport("Shell32.dll", CharSet = CharSet.Auto)]
internal extern static System.IntPtr SHBrowseForFolder(ref BrowseInfo bi);
[DllImport("Shell32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool SHGetPathFromIDList(IntPtr pidl, [MarshalAs(UnmanagedType.LPTStr)] System.Text.StringBuilder pszPath);
[DllImport("User32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool SendMessage(IntPtr hwnd, int msg, IntPtr wp, IntPtr lp);
[DllImport("Shell32.dll")]
internal extern static int SHGetMalloc([MarshalAs(UnmanagedType.IUnknown)]out object shmalloc);
[DllImport("user32.dll")]
internal extern static IntPtr GetActiveWindow();
[DllImport("shell32.dll")]
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);
//Helper routine to free memory allocated using shells malloc object
internal static void SHMemFree(IntPtr ptr)
{
object shmalloc = null;
if (SHGetMalloc(out shmalloc) == 0)
{
IMalloc malloc = (IMalloc)shmalloc;
(malloc).Free(ptr);
}
}
}
}
From: FolderBrowserDialog Unmasked: Everything You Wanted To Know About The Folder Browser Component From .Net Framework
No Filtering
The FolderBrowserDialog has no support for filtering. For example, it is not possible to display only network folders or only shared folders or only folders starting with the string "Documents" or files having a particular extension.
try using the openFileDialog and setup your filters.
Found the answer:
The ComputerBrowserDialog
http://discoveringdotnet.alexeyev.org/2008/04/how-to-browse-for-computer-name.html
I tweeked it a bit to behave more like the FolderBrowserDialog (only took a few min). Works just how I want it to.
精彩评论