Solved

How to get default printer?

Posted on 2004-04-09
19
2,495 Views
Last Modified: 2013-11-20
I use this function:
GetDefaultPrinter(..,..) to get the printer name, I have
include the header files:
#include "winspool.h"
#include "windows.h"

I also upgradte latest SDK, but still GetDefaultPrinter is  undefined, My computer is windowXP.

Thanks.
Hanqian
0
Comment
Question by:Hanqian
  • 7
  • 4
  • 4
  • +3
19 Comments
 
LVL 14

Expert Comment

by:wayside
ID: 10793729
Did you add winspool.lib to the list of libraries to link in?

Project Properties->Linker->Input, add it to the end of the "Additional dependencies" line (for VC++.Net).
0
 

Author Comment

by:Hanqian
ID: 10794069
I added it , but it still doesn't recognize GetDefaultPrinter(..,..).

Thanks.
Hanqian
0
 
LVL 8

Expert Comment

by:gelbert
ID: 10794249
Made sure that your DevStudio is looking at correct version of header files and library. Check how many copies of them you have on your machine.
0
 
LVL 14

Expert Comment

by:wayside
ID: 10794485
Can you give us the *exact* error message, making sure it has the error number? And tell us which version of VisualStudio you are using?

I just created a new SDI project from scratch, added a call to GetDefaultPrinter(), and built it. It worked perfectly without me having to specify any extra libraries. Examination of the exe shows that it pulls it out of winspool.drv . This is on VC++.Net 2003.
0
 

Author Comment

by:Hanqian
ID: 10794513
Error:
error C2065: 'GetDefaultPrinter' : undeclared identifier

version of VisualStudio:
MSDEV98.

Thanks.
Hanqian
0
 
LVL 14

Expert Comment

by:wayside
ID: 10794609
Open up winspool.h and search for GetPrinterDefault. It's not a supported function on windows 98, so your development environment may not know about it even though you are running XP. An up-to-date SDK probably has it, in which case you need to make sure that the SDK include directories are being checked before the VisualStudios directories.

0
 
LVL 4

Expert Comment

by:bkfirebird
ID: 10795121
i agree with wayside, it want working on mine too, until i got the latest sdk from
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10795283
You can use the function in the following url:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;246772
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10803770
This is because this function is Included in Windows 2000 and later so if your application's target OS is not specified explicitly win2k it wan't compile and it gives error because in spool.h definition of this function is conditionally included. better way is to check the os and accordingly call the function. please tell me your application's target os and I will provide you code.
in 9x and NT you have to do little trick( I know it and I did it in my application)


vijay
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:Hanqian
ID: 10805836
Hi Wayside,

I have found that in latest installed SDK in my Program File directory, Winspool.h has
GetDefaultPrinter, but not in WinSpool.h  which is in Program File/Microsoft Visual Studio/ directory
, how to make sure that the SDK include directories are being checked before the VisualStudios directories??
Why SDK doesn't overwrite the same files in Visual Studio??

Thanks.

Hi Vijay,
I am not quite sure what application's target os means, my application works for Window 2000
, Window NT and WIndowXp.

Thanks.
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10805980
     if(m_nOsVer == NT4)
      {
            if(!szDefPrnName)
            {
                  WriteLog("Printer name not specified for %s",szPrnName);
                  return FALSE;
            }
            HKEY  hKey=NULL;
            TCHAR valbuff[MAX_PATH];
            ZeroMemory(valbuff,MAX_PATH);
            DWORD dwType = REG_SZ;
            DWORD cbBuff  = MAX_PATH;
            char* buff = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices");
      
            long result = RegOpenKeyEx(HKEY_CURRENT_USER,buff,NULL,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey);
            if(ERROR_SUCCESS != result )
            {
                  WriteLog("GetDefaultPrn: Error accessing Registery ");
                  return FALSE;
            }
            bRet = RegQueryValueEx(hKey,szDefPrnName,NULL,&dwType,(BYTE*)valbuff,&cbBuff);
            if(ERROR_SUCCESS != bRet)
            {
                  WriteLog("GetDefaultPrn: Error accessing Registery ");
                  return FALSE;
            }
            if(!valbuff || _tcslen(valbuff) <= 0)
            {
                  m_bNoDefPrn = TRUE;
                  return FALSE;
            }
            _tcscat(szDefPrnName,",");
            _tcscat(szDefPrnName,valbuff);
            RegCloseKey(hKey);
            buff = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
            result = RegOpenKeyEx(HKEY_CURRENT_USER,buff,NULL,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey);
            if(ERROR_SUCCESS != result )
            {
                  WriteLog("GetDefaultPrn: Error accessing Registery ");
                  return FALSE;
            }
            bRet= RegSetValueEx(hKey,_T("Device"),NULL,dwType,(const BYTE*)szDefPrnName,_tcslen(szDefPrnName));
            bRet= (bRet==ERROR_SUCCESS);
            RegCloseKey(hKey);
      

      }
      else if(m_nOsVer >= WIN2K)
      {
            typedef BOOL ( WINAPI *SETDEFPRN)(LPCSTR );
            //Old version of winspool.drv may not have this function so
            //better check it out.
            HINSTANCE hSpoolib = LoadLibrary(_T("winspool.drv"));
            if(hSpoolib)
            {
                  SETDEFPRN SetDefPrn = (SETDEFPRN)GetProcAddress(hSpoolib,_T("SetDefaultPrinterA"));
                  if(SetDefPrn)
                  {
                        if(!SetDefPrn((LPCSTR)szPrnName))
                        {
                              WriteLog("Failed to set printer %s default",szPrnName);
                              bRet = FALSE;
                        }
                        //else// default printer is set
                        //      m_bDefPrnSet = TRUE;//so do not take care about default printer now onward
                  }
                  else
                  {
                        WriteLog("Function SetDefaultPrinter not found");
                        bRet = FALSE;
                  }
                  FreeLibrary(hSpoolib);

            }
            else
            {
                  WriteLog("Load library %s failed",_T("winspool.drv"));
                  bRet = FALSE;
            }
      }//IF >= WIN2K
0
 

Author Comment

by:Hanqian
ID: 10806130
Hi Vijay,

I tried just this part code:  else if(m_nOsVer >= WIN2K), it doesn't work, it returns
printer name with garbage.

Thanks.
0
 

Author Comment

by:Hanqian
ID: 10806268
Hi Vijay,

Since I am getting Default info. Should this line code :
 SETDEFPRN SetDefPrn = (SETDEFPRN)GetProcAddress(hSpoolib,_T("SetDefaultPrinterA"));
be:
 GETDefPrn = (GETDEFPRN)GetProcAddress(hSpoolib,_T("GetDefaultPrinterA")); ??

Hanqian

0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10806307
When you look at  http://support.microsoft.com/default.aspx?scid=kb;EN-US;246772

you will see two functions: DPGetDefaultPrinter() and DPSetDefaultPrinter()

These functions works for all versions of Windows and written by Microsoft, which will work fine (I didn't try yet, 'cos I don't have a chance to).

So those functions will do all *tricks* and stuff..

Caner
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10806388
is printspooler service is running ?
because this code is working fine here
0
 
LVL 14

Accepted Solution

by:
wayside earned 100 total points
ID: 10806550
>, how to make sure that the SDK include directories are being checked before the
>VisualStudios directories??

Open up the "Tools" pulldown menu and select "Options".
 Click the tab that says "Directories", you should see a combo box labeled "Show directories for:", pull this down and select "Include files".

You should see directories for VC++, and then at the bottom a directory for the SDK. For example, mine shows

C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE
C:\Program Files\Microsoft SDK\Include

Make sure the directory for the SDK is at the bottom.

If there is no entry for the SDK, you can add one. There should be a rectangle at the bottom of the list, if you double-click in it you can enter another directory or browsae for one.

The same is true for the Library files pulldown from the combo box. Mine shows

C:\Program Files\Microsoft SDK\Lib

for the SDK.

Also for "Executable files", mine has at the bottom

C:\Program Files\Microsoft SDK\Bin
C:\Program Files\Microsoft SDK\Bin\WinNT


> Why SDK doesn't overwrite the same files in Visual Studio??

That's just not how the installer does it. It creates its own directories for the SDK, and then can modify the VS environment to look there first.

0
 

Author Comment

by:Hanqian
ID: 10806606
Hi Caner,

I have tried it, it wouldn't complie for me, it complaints:

///////////////////////////////////
 fnGetDefaultPrinter = GetProcAddress(hWinSpool, GETDEFAULTPRINTER);
      if (!fnGetDefaultPrinter)
      {
        FreeLibrary(hWinSpool);
        return FALSE;
      }

      bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);
///////////////////////////////////////////////////////
fnGetDefaultPrinter(pPrinterName, pdwBufferSize):too many actual parameters

Thanks.

0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10806964
in your projec settings goto c++ and preprocessor catategory set
additional include directories with your path to sdk include like

e:\program files\Microsoft SDK\include

make sure that printspooer service is running and you have some printer set and make it default and just run following program

#include "stdio.h"
#include "windows.h"
#include "winspool.h"

int main(int argc, char* argv[])
{
    char szPrnName[250];
      DWORD dwSize = 250;
      if(!GetDefaultPrinter(szPrnName,&dwSize))
      {
            int d = GetLastError();
            if(d == ERROR_INSUFFICIENT_BUFFER)
                  printf("ERROR_INSUFFICIENT_BUFFER");
            else
                  if(d == ERROR_FILE_NOT_FOUND)
                        printf("ERROR_FILE_NOT_FOUND");
      }
      printf("Default printer %s \n",szPrnName);
      return 0;
}

0
 

Author Comment

by:Hanqian
ID: 10807214
Hi wayside,

Finialy I got it work, you said:

You should see directories for VC++, and then at the bottom a directory for the SDK. For example, mine shows
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE
C:\Program Files\Microsoft SDK\Include
Make sure the directory for the SDK is at the bottom.

But it didn't work until I put the directory for the SDK is at the top. Now i get the function
GetDefaultPrinter works now. Thank you so much.
My thanks  also goes all the people who have help me here.

Hanqian.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Decoding 32 bit binary streams 6 37
Replacement selected text 2 58
fizzArray  challenge 1 57
JQuery serialize and unserialize 8 48
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now