Announcement

Collapse
No announcement yet.

EnumPrinters API

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • EnumPrinters API

    It seems that Windows XP SP3 has done something to change the EnumPrinters API. I have a program that resides on a shared drive mapped to a drive letter and it uses the EnumPrinters API to get the listing of local printers that are available on the local machine (Flags = %PRINTER_ENUM_LOCAL Or %PRINTER_ENUM_CONNECTIONS Or %PRINTER_ENUM_NETWORK). This has always worked just fine until clients started upgrading their machines to the newest service packs. Now the EnumPrinters call works *if* the program is run from the local hard disk, but fails if run from a mapped network drive. I have searched google and can't find a solution to this problem, and was wondering has anyone else here encountered this.

    Any Ideas? I've already added the server as a "Trusted" server, and removed all firewalls between the client and server. Program launches fine, just the EnumPrinters call returns NULL.

    Scott
    Scott Slater
    Summit Computer Networks, Inc.
    www.summitcn.com

  • #2
    You may have to twink with the PRINTER_ENUM_xxxx flags:

    http://msdn.microsoft.com/en-us/libr...92(VS.85).aspx

    Specifically, I don't see you using PRINTER_ENUM_SHARED. (that 'local' difference you mention is what pokes me in this direction).

    MCM
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      I'll Try, but the shared printers all show up if the .EXE is run from a local folder. If the .EXE is run from a remote folder is when it shows NOTHING, not even the local printers. SP3 in XP, and SP2 under Vista broke this. It has worked for years before this. :confused2:

      I am thinking that there is a security patch somewhere now, since a remotely run .EXE seems to have less privileges than the very same ap run from a local disk drive. It shows ALL printers as expected when run from the local disk, but copy the .EXE to a remote folder and run it from there, and you get nothing.
      Last edited by Scott Slater; 12 Oct 2009, 08:03 AM.
      Scott Slater
      Summit Computer Networks, Inc.
      www.summitcn.com

      Comment


      • #4
        Might you be suffering permissions issues?

        I really want to help you on this one, because sometime this week I will be adding code to a client application to let him choose a printer.... and this is the first app for this client which is going to be installed in a common folder for all users to share, including some who log in via some Citrix black magic thing.

        I may have the same problem, although in my case the first thing I had to do was change some code because the user has a couple of remote NT4 machines and there are a couple of Win2K+ only functions which are not supported on those.


        MCM
        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Question 1: Does this work?
          Code:
          #COMPILE EXE
          #REGISTER NONE
          #DIM ALL
          #INCLUDE "WIN32API.INC"
          FUNCTION IsWin95() EXPORT AS LONG
            LOCAL vi AS OSVERSIONINFO
            vi.dwOsVersionInfoSize = SIZEOF(vi)
            GetVersionEx vi
            FUNCTION = (vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS)
          END FUNCTION
          FUNCTION GetPrinters AS STRING
            ON ERROR GOTO GetPrinterError
            DIM Level AS LONG
            DIM Needed AS LONG
            DIM returned AS LONG
            DIM Element AS LONG
            DIM Pi5(0:0) AS PRINTER_INFO_5
            DIM Pi2(0:0) AS PRINTER_INFO_2
            LOCAL Answer AS STRING
            IF IsWin95 THEN
               Level = 5
            ELSE
               Level = 2  'Printer structure to use
            END IF
            IF Level = 5 THEN
              'First call to see how big WINDOWS 95 printer_info_5 structure
              EnumPrinters %PRINTER_ENUM_LOCAL, BYVAL 0, Level, BYVAL %NULL, _
                  BYVAL 0, needed&, returned&
              REDIM PI5(needed& / SIZEOF(Pi5(0)))' AS Printer_Info_5 'Dim using size of structure
              EnumPrinters %PRINTER_ENUM_LOCAL, BYVAL 0, BYVAL Level, _
                  BYVAL VARPTR(PI5(0)), needed&, needed&, returned&
              FOR element = 0 TO returned-1
                Answer = Answer + PI5(Element,0)[email protected] _  'printer name
                                + ","                          _  'comma
                                + PI5(Element,1)[email protected]    _  'port name
                                + ","
              NEXT
              Answer = LEFT$(Answer,LEN(Answer)-1)
            ELSE  '   Windows NT or 2000
              'First call to see how big the WINDOWS NT PRINTER_INFO_2 structure should be
              EnumPrinters %PRINTER_ENUM_CONNECTIONS OR %PRINTER_ENUM_LOCAL OR %PRINTER_ENUM_NETWORK, _
                      BYVAL %NULL, Level, BYVAL %NULL, 0, needed&, returned&
              REDIM PI2(Needed& \ SIZEOF(PI2(0)) + 1)
              EnumPrinters %PRINTER_ENUM_CONNECTIONS OR %PRINTER_ENUM_LOCAL OR %PRINTER_ENUM_NETWORK, _
                      "", Level, BYVAL VARPTR(PI2(0)), SIZEOF(PI2(0)) * (UBOUND(PI2(1)) + 1), _
                      needed&, returned&
              FOR element = 0 TO returned& -1
                'Printer$(element,0) = TRIM$(PI2(Element)[email protected])
                'Printer(element,1) = TRIM$(PI2(Element)[email protected]) 'needed?
                'Printer$(element,1) = RTRIM$(PI2(Element)[email protected])
                Answer = Answer + PI2(Element,0)[email protected] _  'printer name
                                + ","                          _  'comma
                                + PI2(Element,1)[email protected]    _  'port name
                                + ","
              NEXT
              Answer = LEFT$(Answer,LEN(Answer)-1)
            END IF
            FUNCTION = Answer
          ExitGetPrinter:
            EXIT FUNCTION
          GetPrinterError:
            RESUME ExitGetPrinter
          END FUNCTION
          FUNCTION PBMAIN AS LONG
            DIM answer$,printer&,TotalPrinters&,offset&,filenum&,machinenumber$
            answer$   = GetPrinters
            totalprinters& = PARSECOUNT(answer$,",")/2
            IF totalprinters& > 0 THEN
              FOR printer& = 1 TO totalprinters&
                ? PARSE$(answer$,printer&+offset&)  'no on port 1/9/03
                REM Port info
                REM ? PARSE$(answer$,printer&+offset&+1)             'port
                offset& = offset& + 1&
              NEXT
            END IF
          END FUNCTION

          Question 2: Does this work?
          Code:
          #COMPILE EXE
          #DIM ALL
          FUNCTION PBMAIN () AS LONG
            LOCAL ix AS LONG, sPrinters AS STRING
            FOR ix = 1 TO PRINTERCOUNT
              ? PRINTER$(NAME,ix)
            NEXT
            SLEEP 5000
          END FUNCTION
          I need to do some updating if either of these functions fail.

          Thank you
          Last edited by Mike Doty; 13 Oct 2009, 04:28 AM.
          How long is an idea? Write it down.

          Comment


          • #6
            Your first routine is pretty much the exact same call I am making so it would fail in this rare situation. It has to due with a permissions setting somewhere, but so far I have not found what it is.

            Unfortunately, It is a few of my customers with the problem. I had several of these creep up within the past 2 weeks, so it could even be related to a recent update. This code has run for years on shared drives without a problem.

            We were able to figure out when the problem occurred and when it didn't by me having them try some different things over the phone. I don't have a system here that I can replicate this on, but plan on using an SP3 XP CD to load a machine in VMWare and hopefully I get the same issue so that I can do some investigating. My version of Vista Business does not do this, My customers Vista Home Premium did. As stated earlier, the problem only arises when the .EXE is executed from a remote (ie mapped network) path. The very same .EXE works perfectly as expected when executed from the local hard disk.

            If I have to I will simply change the way they install their program and have them install on the local drive and then share only the data. It would be nice however to find the cause if this problem.

            I also talked to a different customer yesterday who is running XP SP3 with no problems what so ever. So it apparently isn't all systems for some reason. All people involved are logged in with an ADMIN account. I'll advise as soon as I figure something out. Hopefully I can replicate the problem here.
            Scott Slater
            Summit Computer Networks, Inc.
            www.summitcn.com

            Comment


            • #7
              Need to see if the PB only code works.
              I have XP SP3 and Vista 32-bit Home Premium if that is of any help.
              Code:
              FUNCTION PBMAIN () AS LONG
                LOCAL ix AS LONG
                FOR ix = 1 TO PRINTERCOUNT
                  ? PRINTER$(NAME,ix)
                NEXT
              END FUNCTION
              The above code would make life easier if it works in all situations.
              Would like to fix this before Windows 7 comes out which might make it harder to isolate.

              Thanks
              Last edited by Mike Doty; 13 Oct 2009, 08:23 AM.
              How long is an idea? Write it down.

              Comment


              • #8
                Update:

                I have installed SP3 on my XP and it still works as expected. I am not sure why my customers are having this problem. Will need to investigate further.

                Mike, The PB-ONLY code works as well, and it also works fine on Win7 (x64) and (x86) final builds as well.

                I would say that you are safe to use it.
                Scott Slater
                Summit Computer Networks, Inc.
                www.summitcn.com

                Comment


                • #9
                  May be best to switch to the PB function.
                  Thanks for the update.
                  How long is an idea? Write it down.

                  Comment

                  Working...
                  X