Forum: PC-Programmierung CMD: drucker druckt nicht


von Leonard H. (Gast)


Lesenswert?

Hi,

ich versuche gerade den meine Drucker (HP Deskjet 3050a) über ein 
simples C Programm anzusteuern! Es gibt aber immer nur eine Datei mit 
dem Druckernamen aus, aber der Drucker gibt keinen Mucks von sich!
Ich habe mal probiert den Drucker über die CMD anzusteuern, mit diesem 
Befehl:
print /D:"Hauptdrucker"  C:\test.txt
die Syntax ist richtig und die Console gibt aus das die Datei gedruckt 
wird,
doch auch diesmal kommt nichts am Drucker an!
Mit einem normalen Texteditor funktioniert der Drucker fehler frei.
Kann das vielleicht daran liegen das der Drucker ein USB-Drucker ist?
Oder muss man vielleicht den Port angeben?
Anbei noch der C code.

Danke,
Leonard
1
/*************************************************
2
*            b s p l 0 0 7 4 . c                 *
3
*------------------------------------------------*
4
*  Aufgabe : Formatierter Druck von Textdateien  *
5
*------------------------------------------------*
6
*  Autor   : Erlenkötter                         *
7
*  Stand   : 28.05.99                            *
8
*------------------------------------------------*
9
*  Compiler: <hier Compiler-Optionen eintragen>  *
10
*************************************************/
11
12
/*----- include files --------------------------*/
13
#include <stdio.h>
14
#include <string.h>
15
#include <stdlib.h>
16
17
/*----- define ---------------------------------*/
18
#define SEITENLAENGE 65
19
/* PCL-Steuerzeichen für Schmalschrift */
20
#define SCHMAL "1B2873313648"
21
/* Steuerzeichen für Seitenvorschub */
22
#define NEUE_SEITE "0c"
23
/* PCL-Steuerzeichen für normale Schrift */
24
#define NORMAL "1B2873313248"
25
/* maximale Zeilenlänge */
26
#define MAX_EINGABE 200
27
28
FILE *text;    /* Druckausgabe */
29
30
/*************************************************
31
*  Funktion   : l e f t _ m a r g i n            *
32
*------------------------------------------------*
33
*  Aufgabe    : Leerzeichen für Zeilenanfang     *
34
*  Parameter  : Anzahl der Leerstellen           *
35
*  Return-Wert: keiner                           *
36
*************************************************/
37
void left_margin(int rand) {
38
  while(rand-- > 0)
39
    fprintf(text,"%c",32);  /* 32 = ASCII-Code
40
                               für Leerzeichen */
41
}
42
43
/*************************************************
44
*  Funktion   : k o p f z e i l e                *
45
*------------------------------------------------*
46
*  Aufgabe    : Kopfzeilenausgabe einer Liste    *
47
*  Parameter  : Name der zu druckenden Datei     *
48
*             : Abstand vom linken Rand          *
49
*  Return-Wert: keiner                           *
50
*************************************************/
51
void kopfzeile(char *dateiname,int linker_rand) {
52
  static int seite=1;
53
  fprintf(text,"\n");       /* 1 Leerzeile vor
54
                                 Druckbeginn */
55
  left_margin(linker_rand);
56
  fprintf(text,
57
        "<<< Seite %3i >>>   von %s\n\n",
58
        seite++,dateiname);
59
}
60
61
/*************************************************
62
*  Funktion   : s t e u e r z e i c h e n        *
63
*------------------------------------------------*
64
*  Aufgabe    : Steuerzeichen an Drucker senden  *
65
*  Parameter  : Escape-Sequenz                   *
66
*  Return-Wert: keiner                           *
67
*************************************************/
68
void steuerzeichen(char *seq) {
69
  char wert;
70
  while(*seq) {              /* Lies die gesamte
71
                                Steuersequenz */
72
    sscanf(seq,"%2x",&wert);/* Hole jeweils 2
73
                               Zeichen */
74
    fprintf(text,"%c",wert);
75
    seq+=2;
76
  }
77
}
78
79
/*----- Hauptprogramm --------------------------*/
80
main() {
81
  FILE *stream;
82
  char dateiname[67]; /* zu druckende Datei  */
83
  int zeile=0;        /* aktuelle Druckzeile */
84
  int linker_rand=10; /* linke Randgröße     */
85
  char schmal='J';    /* Schmalschrift J/N ? */
86
  char eingabe[MAX_EINGABE];  /* Dialogzeile */
87
  printf("\n\t\t<<< Formatierter Druck >>>");
88
  printf("\n\n<RETURN> beendet das Programm.\n");
89
90
  /*----- Dateinamen einlesen und öffnen */
91
  printf("\nWelche Datei drucken?\n>");
92
  gets(dateiname);
93
  if(strlen(dateiname) == 0)
94
    exit(0);
95
  while((stream = fopen(dateiname,"r")) == NULL) {
96
    printf("'%s' nicht gefunden!\a\n",dateiname);
97
    printf("\nWelche Datei drucken?\n>");
98
    gets(dateiname);
99
    if(strlen(dateiname) == 0)
100
      exit(0);
101
  }
102
103
  /*----- Druckparameter einlesen */
104
  printf("\n<RETURN> uebernimmt die Vorgaben.\n");
105
  printf("\nLinker Rand (%i): >",linker_rand);
106
  gets(eingabe);
107
  if(strlen(eingabe) != 0)
108
    linker_rand = atoi(eingabe);
109
  printf("\nSchmalschrift J/N (%c): >",schmal);
110
  gets(eingabe);
111
  if(strlen(eingabe) != 0) {
112
    if(eingabe[0] == 'N' || eingabe[0] == 'n')
113
      schmal = 'N';
114
  }
115
116
  /*----- Druckausgabe öffnen */
117
118
  text = fopen("Hauptdrucker","a");
119
  if (text == NULL) {
120
    printf("Fehler beim Oeffnen von LPT1");
121
    exit(1);
122
  }
123
124
  /*----- Schriftart einstellen */
125
  if(schmal == 'J')
126
    steuerzeichen(SCHMAL);
127
  else
128
    steuerzeichen(NORMAL);
129
130
  /*----- Liste drucken */
131
  kopfzeile(dateiname,linker_rand);
132
  while(fgets(eingabe,MAX_EINGABE,stream)!=NULL) {
133
    left_margin(linker_rand);
134
    fprintf(text,"%s",eingabe);
135
    if(++zeile > SEITENLAENGE-10) {
136
      steuerzeichen(NEUE_SEITE);
137
      kopfzeile(dateiname,linker_rand);
138
      zeile=0;
139
    }
140
  }
141
  steuerzeichen(NEUE_SEITE);
142
143
  /*----- Datei schliessen */
144
  fclose(stream);
145
146
  printf("\nDruck beendet!\a\n");
147
}

von g457 (Gast)


Lesenswert?

>  text = fopen("Hauptdrucker","a");
>  if (text == NULL) {
>    printf("Fehler beim Oeffnen von LPT1");

Vielleicht nochmals die Doku zu fopen() lesen.

von Leonard H. (Gast)


Lesenswert?

warum?

von g457 (Gast)


Lesenswert?

> warum?

Leg doch mal in kurzen Worten dar, was obig zitierter Aufruf von fopen() 
machen soll, was er tatsächlich macht, was das mit dem ebefalls 
zitierten LPT1 zu tun hat, und wie du das ganze mit einem USB-Drucker 
verheiratest.

Eben, also lies bitte die Doku.

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

> text = fopen("Hauptdrucker","a");
>  if (text == NULL) {
>    printf("Fehler beim Oeffnen von LPT1");

Die Fehlermeldung ist aber irreführend.
Sollte da nicht eher "Fehler beim Oeffnen von .\\Hauptdrucker" stehen ?

von Frank K. (fchk)


Lesenswert?

X. H. schrieb:

> Kann das vielleicht daran liegen das der Drucker ein USB-Drucker ist?

Das nicht direkt. Der Haken ist, dass Dein Drucker ziemlich dumm ist und 
im Prinzip nur Pixel drucken kann. Die Intelligenz steckt wie bei vielen 
billigen Druckern im Druckertreiber. Du versuchst hingegen, den Drucker 
direkt anzusteuern, ohne über den Windows Druckertreiber zu gehen, und 
das geht bei Deinem Drucker nicht. Du musst übers Win32 API und das GDI 
gehen.

Lies das hier:
http://www.dreamincode.net/forums/topic/194320-win32-api-printer-tutorial-using-gdi-functions/

fchk

PS: ... oder per MFC oder eine andere Klassenbibliothek. Intern machen 
die aber genau das gleiche.

: Bearbeitet durch User
von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Frank K. schrieb:
> X. H. schrieb:
>
>> Kann das vielleicht daran liegen das der Drucker ein USB-Drucker ist?
>
> Das nicht direkt. Der Haken ist, dass Dein Drucker ziemlich dumm ist und
> im Prinzip nur Pixel drucken kann. Die Intelligenz steckt wie bei vielen
> billigen Druckern im Druckertreiber. Du versuchst hingegen, den Drucker
> direkt anzusteuern, ohne über den Windows Druckertreiber zu gehen, und
> das geht bei Deinem Drucker nicht. Du musst übers Win32 API und das GDI
> gehen.
>

Eine lokale Datei namens "Hauptdrucker" anstatt des Gerätes zu öffnen 
kann man nicht als Versuch bezeichnen.

von leonard (Gast)


Lesenswert?

Dennis Heynlein schrieb:
>> text = fopen("Hauptdrucker","a");
>>  if (text == NULL) {
>>    printf("Fehler beim Oeffnen von LPT1");
>
> Die Fehlermeldung ist aber irreführend.
> Sollte da nicht eher "Fehler beim Oeffnen von .\\Hauptdrucker" stehen ?

ja, habe den Quellcode aber nur abgeschrieben und noch nicht jedes 
Detail korigiert. Habe es aber jetzt gemacht!
Immerhin weis ich ja noch nicht wie der Name oder Schnittstelle lauten 
muss damit es endlich funktioniert.


Dennis Heynlein schrieb:
> Eine lokale Datei namens "Hauptdrucker" anstatt des Gerätes zu öffnen
> kann man nicht als Versuch bezeichnen.

Ich habe es schon mit dem Namen ("Hauptdrucker") mit dem öffentlichen 
Namen ("Drucker17") und mit dem Anschluss (USB001) probiert.
Die Console hat wie gesagt immer bei ersten mal ausgegeben, das die 
Datei gerade gedruckt wird, aber am Drucker selbst kamm nichts an. Beim 
zweiten, dritten,... mal hat das dann aber nicht mehr funktioniert, ich 
denke da die vorherige Datei noch nicht fertiggestellt wurde.


Frank K. schrieb:
> Lies das hier:
> 
http://www.dreamincode.net/forums/topic/194320-win32-api-printer-tutorial-using-gdi-functions/

Werde ich mir mal anschauen.

leonard

von leonard (Gast)


Lesenswert?

sorry,

vielleicht ist das etwas ireführend beschrieben:
es geht mir eigentlich darum ein C Programm zu schreiben
das dateien bearbeiten und dann drucken kann. Da dies aber
nicht funktioniert hat wollte ich es erstmal über
die CMD probieren, da ich dachte es währe etwas leichter und
übersichtlicher.
Ich bräuchte jetzt erstmal eine Lösung für die CMD, und für das
C Programm erst wenn das mit der CMD funktioniert!

leonard

von mr, mo (Gast)


Lesenswert?

Du bist doch ein Troll oder?

g457 schrieb:
> Vielleicht nochmals die Doku zu fopen() lesen.

Mach das!

Glaubst du tatsächlich das du einen Drucker so einfach mit Daten 
fütterst? Woher soll das Programm wissen was für einen Drucker er vor 
sich hat? Woher soll es wissen wie der Drucker angesprochen wird? Das 
ganze ist nicht so einfach wie du es dir da vorstellst.

Wo hast du das überhaupt abgeschrieben?

von uwe (Gast)


Lesenswert?


von Frank K. (fchk)


Lesenswert?

leonard schrieb:
> sorry,
>
> vielleicht ist das etwas ireführend beschrieben:
> es geht mir eigentlich darum ein C Programm zu schreiben
> das dateien bearbeiten und dann drucken kann. Da dies aber
> nicht funktioniert hat wollte ich es erstmal über
> die CMD probieren, da ich dachte es währe etwas leichter und
> übersichtlicher.

falsch.

> Ich bräuchte jetzt erstmal eine Lösung für die CMD, und für das
> C Programm erst wenn das mit der CMD funktioniert!

Noch falscher.

Unter Windows gibt es verschiedene Arten von ausführbaren Dateien:
- DLLs
  - 16 Bit (geht nicht mehr mit 64 Bit Windows)
  - 32 Bit
  - 64 Bit (geht nur mit 64 Bit Windows)
- EXE
  - für MS-DOS (geht nicht mehr mit 64 Bit Windows)
  - für 16-Bit Windows (geht nicht mehr mit 64 Bit Windows)
  - 32 Bit Konsolenapplikation (wie DOS-Programm, aber 32 Bittig und mit 
Zugriff auf die NT-Betriebssystemfunktionen)
  - 32 Bit Windows-GUI-Applikationen
  - 64 Bit Konsolenapplikation (geht nur mit 64 Bit Windows)
  - 64 Bit Windows-GUI-Applikationen (geht nur mit 64 Bit Windows)

Um auf das ganze Grafiksystem und die Windows-Druckertreiber zugreifen 
zu können, musst(!) Du eine Windows-GUI-Applikation schreiben. Die 
Mittel und Wege sind Dir freigestellt, aber es muss eine GUI-Applikation 
sein. Das heißt für Dich, dass Du kein main(), sondern ein WinMain() 
hast, ein InitInstance() machen musst, etc ppp - was man eben bei einer 
Windows-Applikation so machen muss, und der Header der erzeugten .exe 
mit als Windows GUI Executable markiert sein. Es gibt mehr als genug 
Bücher und Beispielcode von Microsoft zu dem Thema, für C, C++/MFC, C#, 
VB.Net.

Dein jetziger Ansatz führt zu nichts.

fchk

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

leonard schrieb:
> sorry,
> ................

Beispiel.
Läuft auch im CMD
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <windows.h>
4
5
char printerdata[100]="HELLO WORLD";
6
char mydoc[]="My Document";
7
char datatype[]="RAW";
8
9
int main() {
10
    HANDLE hPrinter = NULL;
11
    DWORD bStatus = OpenPrinter("Microsoft Office Document Image Writer", &hPrinter, NULL);
12
    if(bStatus) {
13
        DOC_INFO_1 DocInfo;
14
        DocInfo.pDocName = mydoc;
15
        DocInfo.pOutputFile = NULL;
16
        DocInfo.pDatatype = datatype;
17
        DWORD dwJob = StartDocPrinter(hPrinter, 1, (LPBYTE)&DocInfo);
18
        if(dwJob > 0) {
19
            bStatus = StartPagePrinter(hPrinter);
20
            if(bStatus) {
21
                DWORD dwBytesWritten;
22
                bStatus = WritePrinter(hPrinter, printerdata, strlen(printerdata), &dwBytesWritten);
23
                EndPagePrinter(hPrinter);
24
            }
25
           EndDocPrinter(hPrinter);
26
        }
27
        ClosePrinter(hPrinter);
28
    }
29
    return 0;
30
}

: Bearbeitet durch User
von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Variante 2: (Über Winspool und GDI)
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <windows.h>
4
5
int main() {
6
    HDC hDC;
7
    DOCINFO di;
8
9
    hDC= CreateDC("WINSPOOL","Microsoft XPS Document Writer",NULL,NULL);
10
    memset(&di,0,sizeof(DOCINFO));
11
    di.cbSize= sizeof(DOCINFO);
12
    di.lpszDocName= "Sample Document";
13
14
    if(StartDoc(hDC,&di)>0) {
15
        char buffer1[]= "This is output to the printer";
16
17
        StartPage(hDC);
18
        TextOut(hDC,10,10,buffer1,sizeof(buffer1)-1);
19
        EndPage(hDC);
20
        EndDoc(hDC);
21
    }
22
    DeleteDC(hDC);
23
    return 0;
24
}

: Bearbeitet durch User
von leonard (Gast)


Lesenswert?

Frank K. schrieb:
> Um auf das ganze Grafiksystem und die Windows-Druckertreiber zugreifen
> zu können, musst(!) Du eine Windows-GUI-Applikation schreiben.

Ich dachte GUI ist einfach ein Programm mit grafischer Oberfläche, geht 
das nicht auch direkt in der Console???

Ich werde mal den Code von  Dennis Heynlein ausprobieren.
lh

von Georg (Gast)


Lesenswert?

leonard schrieb:
> Ich dachte GUI ist einfach ein Programm mit grafischer Oberfläche, geht
> das nicht auch direkt in der Console???

Du kannst in einem Consolenprogramm schon einen einfachen print-Befehl 
ausführen, aber der durchläuft das ganze System mit Grafik-Canvas und 
Druckertreiber wie ein Grafikausdruck auch. Es ist im Gegenteil eher 
schwierig in Windows so etwas wie eine ESC-Sequenz direkt an den Drucker 
zu schicken, dazu braucht man einen Raw-Modus. Grundsätzlich sendet man 
in Windows nicht ESC irgendwas, sondern selektiert eine andere Schrift 
usw.

Man kann mit copy eine Datei an eine Druckerschnittstelle schicken, aber 
es gibt nur noch wenige Drucker, die tatsächlich HelloWorld aufs Papier 
drucken, wenn man den ASCII-Text schickt. Fast alle Drucker sind 
Seitendrucker und drucken nicht zeichenweise.

Georg

von Dirk B. (dirkb2)


Lesenswert?

Es gibt zum einfachen ausdrucken unter Windows auch 
http://www.lerup.com/printfile/

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

> Um auf das ganze Grafiksystem und die Windows-Druckertreiber zugreifen
> zu können, musst(!) Du eine Windows-GUI-Applikation schreiben.

Warum das ?

Eine Console hat durchaus Zugriff auf den Gerätekontext der Drucker und 
kann mit GDI-befehlen darauf Zeichnen.
Siehe Variante 2 .

Man muß halt schon die GDI32.lib und WINSPOOL.lib linken.

@leonard :

Für ernsthaften Einsatz empfehle ich dir die GDI-Funktionen von Windows 
zu studieren und die Funktionen rund um die Drucker. (z.b. Seitengröße 
etc. abfragen und setzen). Wenn der Drucker mit Treiber in Windows zur 
Verfügung steht sparste dir dieses ganze Befehle senden an den Drucker 
per Hand.

von Frank K. (fchk)


Lesenswert?

Dennis Heynlein schrieb:

> Eine Console hat durchaus Zugriff auf den Gerätekontext der Drucker und
> kann mit GDI-befehlen darauf Zeichnen.
> Siehe Variante 2 .

Danke. Ich hatte immer irgendwo im Hinterkopf, dass da irgendwo eine 
Kleinigkeit fehlte. Ist bei mir aber auch schon eine Weile her mit 
Win32.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.