Listing all printers attached to a user
This code list the associated printers including network printers that are attached/installed under a windows user account.
This code is useful in Web/WCF services.
and it also useful to get the printer for a given Active directory user
public DataTable GetPrinters(string userid,string pwd,string domain)
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("PrinterName");
using (Impersonation imperson =
new Impersonation(userid,domain,pwd)
{
//ManagementScope oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
//oManagementScope.Connect();
SelectQuery oSelectQuery = new SelectQuery();
oSelectQuery.QueryString = @"SELECT * FROM CIM_Printer";
ManagementObjectSearcher oObjectSearcher =
new ManagementObjectSearcher(oSelectQuery);
ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();
foreach (ManagementObject mobj in oObjectCollection)
{
if (dataTable.Select("PrinterName='" + mobj["Name"] + "'").Count() == 0)
{
DataRow row = dataTable.NewRow();
row[0] = mobj["Name"];
dataTable.Rows.Add(row);
}
}
foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
if (dataTable.Select("PrinterName='" + printer + "'").Count() == 0)
{
DataRow row = dataTable.NewRow();
row[0] = printer;
dataTable.Rows.Add(row);
}
}
}
}
Impersonation .cs file
-----------------------------------
using System;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Security.Permissions;
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
{
///
/// Initializes a new instance of the
///
/// Name of the user.
/// Name of the domain.
/// The password.
public Impersonation(string userName, string domainName, string password)
{
ImpersonateValidUser(userName, domainName, password);
}
public void Dispose()
{
UndoImpersonation();
}
#region P/Invoke.
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern int FormatMessage(int dwFlags, ref IntPtr lpSource,
int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr Arguments);
[DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool LoadUserProfile
(IntPtr hToken, ref ProfileInfo lpProfileInfo);
[DllImport("Userenv.dll", CallingConvention =
CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool UnloadUserProfile
(IntPtr hToken, IntPtr lpProfileInfo);
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region Private member.
// ------------------------------------------------------------------
///
/// Impersonates the valid user.
///
/// Name of the user.
/// The domain.
/// The password.
private void ImpersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if (RevertToSelf())
{
if (LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
#region LoadUserProfile
// Load user profile
ProfileInfo profileInfo = new ProfileInfo();
profileInfo.dwSize = Marshal.SizeOf(profileInfo);
profileInfo.lpUserName = userName;
profileInfo.dwFlags = 1;
Boolean loadSuccess = LoadUserProfile(tokenDuplicate, ref profileInfo);
if (!loadSuccess)
{
//Console.WriteLine("LoadUserProfile() failed with error code: " + Marshal.GetLastWin32Error());
//throw new Win32Exception (Marshal.GetLastWin32Error());
//Logger.AddToLog("LoadUserProfile()", GetErrorMessage(Marshal.GetLastWin32Error()));
}
if (profileInfo.hProfile == IntPtr.Zero)
{
//Console.WriteLine( "LoadUserProfile() failed - HKCU handle was not loaded. Error code: " + Marshal.GetLastWin32Error());
//throw new Win32Exception (Marshal.GetLastWin32Error());
//Logger.AddToLog("LoadUserProfile() failed - HKCU handle was not loaded", GetErrorMessage(Marshal.GetLastWin32Error()));
}
#endregion
}
}
// else { Logger.AddToLog("Impersonation", GetErrorMessage(Marshal.GetLastWin32Error())); }
}
}
catch (Exception ex)
{
// Logger.AddToLog(ex);
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
}
// GetErrorMessage formats and returns an error message
// corresponding to the input errorCode.
public static string GetErrorMessage(int errorCode)
{
int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
//int errorCode = 0x5; //ERROR_ACCESS_DENIED
//throw new System.ComponentModel.Win32Exception(errorCode);
int messageSize = 255;
String lpMsgBuf = "";
int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
IntPtr ptrlpSource = IntPtr.Zero;
IntPtr prtArguments = IntPtr.Zero;
int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, prtArguments);
if (0 == retVal)
{
//throw new Exception("Failed to format message for error code " + errorCode + ". ");
//Logger.AddToLog("Impersonation", "Failed to format message for error code " + errorCode + ". ");
}
return lpMsgBuf;
}
///
/// Undoes the impersonation.
///
private void UndoImpersonation()
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}
private WindowsImpersonationContext impersonationContext = null;
// ------------------------------------------------------------------
#endregion
}
[StructLayout(LayoutKind.Sequential)]
public struct ProfileInfo
{
///
/// Specifies the size of the structure, in bytes.
///
public int dwSize;
///
/// This member can be one of the following flags:
/// PI_NOUI or PI_APPLYPOLICY
///
public int dwFlags;
///
/// Pointer to the name of the user.
/// This member is used as the base name of the directory
/// in which to store a new profile.
///
public string lpUserName;
///
/// Pointer to the roaming user profile path.
/// If the user does not have a roaming profile, this member can be NULL.
///
public string lpProfilePath;
///
/// Pointer to the default user profile path. This member can be NULL.
///
public string lpDefaultPath;
///
/// Pointer to the name of the validating domain controller, in NetBIOS format.
/// If this member is NULL, the Windows NT 4.0-style policy will not be applied.
///
public string lpServerName;
///
/// Pointer to the path of the Windows NT 4.0-style policy file.
/// This member can be NULL.
///
public string lpPolicyPath;
///
/// Handle to the HKEY_CURRENT_USER registry key.
///
public IntPtr hProfile;
}
}
Awesome code..it works fine!
Thank u Sateesh...great job.....
Very helpfull....
Thanks & Regards,
Sneha