Click here to Skip to main content
15,881,872 members
Articles / General Programming / Printing
Tip/Trick

Adding a Local Port through XcvData and C#

Rate me:
Please Sign up or sign in to vote.
4.88/5 (8 votes)
10 Jul 2010CPOL 33.2K   3   9
Do you know what a "function for all" is? Well, I will tell you if you didn't know: an absolute disaster. The Winspool XcvData function is a great sample of this: it can be used for so many different thigs and it is so poorly documented that using it becomes an incredible pain in the neck.

I just wanted to add a Local Port... If you want to, maybe you would like to try this way:

C#
public static class Winspool
{
    [StructLayout(LayoutKind.Sequential)]
    private class PRINTER_DEFAULTS
    {
        public string pDatatype;
        public IntPtr pDevMode;
        public int DesiredAccess;
    }

    [DllImport("winspool.drv", EntryPoint = "XcvDataW", SetLastError = true)]
    private static extern bool XcvData(
        IntPtr hXcv,
        [MarshalAs(UnmanagedType.LPWStr)] string pszDataName,
        IntPtr pInputData,
        uint cbInputData,
        IntPtr pOutputData,
        uint cbOutputData,
        out uint pcbOutputNeeded,
        out uint pwdStatus);

    [DllImport("winspool.drv", EntryPoint = "OpenPrinterA", SetLastError = true)]
    private static extern int OpenPrinter(
        string pPrinterName,
        ref IntPtr phPrinter,
        PRINTER_DEFAULTS pDefault);

    [DllImport("winspool.drv", EntryPoint = "ClosePrinter")]
    private static extern int ClosePrinter(IntPtr hPrinter);

    public static int AddLocalPort(string portName)
    {
        PRINTER_DEFAULTS def = new PRINTER_DEFAULTS();

        def.pDatatype = null;
        def.pDevMode = IntPtr.Zero;
        def.DesiredAccess = 1; //Server Access Administer

        IntPtr hPrinter = IntPtr.Zero;

        int n = OpenPrinter(",XcvMonitor Local Port", ref hPrinter, def);
        if (n == 0)
            return Marshal.GetLastWin32Error();

        if (!portName.EndsWith("\0"))
            portName += "\0"; // Must be a null terminated string

        // Must get the size in bytes. Rememeber .NET strings are formed by 2-byte characters
        uint size = (uint)(portName.Length * 2);

        // Alloc memory in HGlobal to set the portName
        IntPtr portPtr = Marshal.AllocHGlobal((int)size);
        Marshal.Copy(portName.ToCharArray(), 0, portPtr, portName.Length);

        uint needed; // Not that needed in fact...
        uint xcvResult; // Will receive de result here

        XcvData(hPrinter, "AddPort", portPtr, size, IntPtr.Zero, 0, out needed, out xcvResult);

        ClosePrinter(hPrinter);
        Marshal.FreeHGlobal(portPtr);

        return (int)xcvResult;
    }
}


I think this might save a lot of time for some of you. With this class, you just have to call the AddLocalPort method, passing the name of the port you want. It will return a System error code (0 means ERROR_SUCCESS).

See you...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Spain Spain
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionMessage Closed Pin
22-Jan-22 13:56
Member 1297052022-Jan-22 13:56 
PraiseNice! Thank you. Pin
Sing Abend7-Jun-19 12:01
professionalSing Abend7-Jun-19 12:01 
QuestionHow to Pin
Travis Citrine13-Mar-15 1:40
Travis Citrine13-Mar-15 1:40 
Questionhow to using?! Pin
c0mmander18-Jun-14 16:42
c0mmander18-Jun-14 16:42 
QuestionGreat work! Pin
steskalj14-Apr-14 8:34
steskalj14-Apr-14 8:34 
QuestionGood job, but ... Pin
CelPlusPlus10-Oct-13 1:31
CelPlusPlus10-Oct-13 1:31 
AnswerRe: Good job, but ... Pin
_Erik_10-Oct-13 3:47
_Erik_10-Oct-13 3:47 
GeneralMy vote of 5 Pin
Member 38079394-Apr-13 22:10
Member 38079394-Apr-13 22:10 
GeneralReason for my vote of 5 Works well without any code redress ... Pin
Leo Pius4-Apr-11 8:59
Leo Pius4-Apr-11 8:59 
GeneralThanks a lot, you really did save me a lot of time with this... Pin
Pavel Khail17-Aug-10 3:36
Pavel Khail17-Aug-10 3:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.