8

I'm using the WMI Code Creator to create code to add a networked printer.

http://img13.imageshack.us/img13/9847/wmicodecreatorwin32prin.png

The code that was generated works great (under my domain account anyway):

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
    public class CallWMIMethod
    {
        public static void Main()
        {
            try
            {
                ManagementClass classInstance =
                    new ManagementClass("root\\CIMV2",
                    "Win32_Printer", null);

                // Obtain in-parameters for the method
                ManagementBaseObject inParams =
                    classInstance.GetMethodParameters("AddPrinterConnection");

                // Add the input parameters.
                inParams["Name"] =  "\\\\PrintServer\\PrinterName";

                // Execute the method and obtain the return values.
                ManagementBaseObject outParams =
                    classInstance.InvokeMethod("AddPrinterConnection", inParams, null);

                // List outParams
                Console.WriteLine("Out parameters:");
                Console.WriteLine("ReturnValue: " + outParams["ReturnValue"]);
            }
            catch(ManagementException err)
            {
                MessageBox.Show("An error occurred while trying to execute the WMI method: " + err.Message);
            }
        }
    }
}

However, I need to add a networked printer to a local PC account, ie a non-domain account that does not have access to \PrintServer.

Where can I put in a domain user's (a service account) username and password into the above code?

I have been Googling for hours but all I can find is that one stupid post that says how to add a printer on a remote machine, which is not what I'm looking to do.

(I need to add a remote printer to the current PC, not to a remote PC.) (The caveat is that the logged on user is a local PC account.)

Does anyone know how this can be achieved?

JohnnyRockets
  • 91
  • 1
  • 4

2 Answers2

1

you could create the same local account on the print server, enabling peer-to-peer authentication by doing so...

i.e. pc1 has user bob1 locally. make bob1 a user on the print server.

run your map program as bob1 on pc1 and you should be able to get to the printer.

does that help?

otherwise, network printers are per user...running your program as the domain user that has access (i.e. runas) wouldn't work since it would simply map the printer to the users session and not the one you actually want.

...what about this? http://www.codescript.co.uk/wmi_connect_as_another_user.htm

...or scriptomatic? http://www.microsoft.com/download/en/details.aspx?DisplayLang=en&id=12028 (even tho it is not for c#, it can still give wmi synatx stuff)

Justin C
  • 647
  • 7
  • 11
  • Unfortunately, I don't have access to modify users or user access on the print server; I only have read access (to my domain account that is). I'll check out those links, but just wanted to respond to that and see if anyone had other suggestions in the meantime. – JohnnyRockets Aug 08 '11 at 14:15
  • perhaps net use works with printer mapping as another user? http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/2000/Q_23440726.html – Justin C Aug 08 '11 at 14:38
  • in case you can't get to the link - the example they used was - NET USE lpt1 "\\ws44a03\HP Lj1300" /user:user user /PERSISTENT:YES – Justin C Aug 08 '11 at 14:39
  • i find some info that supported the previous comment by "skomski" that mentions the guest account on the printer. – Justin C Aug 08 '11 at 14:41
  • honestly, i think you'll need to partner with someone who has access to the print server. – Justin C Aug 08 '11 at 14:41
  • 1
    Thank you Justin! Net use is a suitable workaround. For full disclosure in hopes of helping others, here's the full command I'm using in my program: System.Diagnostics.Process.Start("net", @"use \\printServer /user:domain\username password"); (Note that separation of "net" and the arguments is necessary! Hope that helps save others some frustration and time haha.) I guess it's just not possible to do this via C# (??) but this works for now. Thanks again! – JohnnyRockets Aug 09 '11 at 18:07
0

So since other answer was removed. I just tested this and it worked. Here is link to get the class I am using https://www.codeproject.com/Articles/10090/A-small-C-Class-for-impersonating-a-User Here is the code below which worked for me. If you look there are some even better implementations of classes out there to impersonate users.

    static void Main(string[] args)
    {

        using (new Impersonator("username", "domainName", "myPassword"))
        {
            // The following code is executed under the impersonated user.
            AddPrinterUnc(@"\\PrintServer\printershare");
        }


    }

    public static void AddPrinterUnc(string printUncPath)
    {

            using (ManagementClass oPrinterClass = new ManagementClass(new ManagementPath("Win32_printer"), null))
            {
                using (ManagementBaseObject oInputParameters = oPrinterClass.GetMethodParameters("AddPrinterConnection"))
                {
                    oInputParameters.SetPropertyValue("Name", printUncPath);

                    oPrinterClass.InvokeMethod("AddPrinterConnection", oInputParameters, null);

                }
            }

    }
JMIII
  • 320
  • 2
  • 16