Setting PrinterName and Trayname in a Windows Service
The method below prints Report Archive Files from a Windows Service. The
problem I am having is the assignment of PrinterName and TrayName does not
"stick" when set in code.
I am writing out the PrinterName and TrayName before and after the
assignment to lPrinterDevice.Printer.PrinterName:= PrinterGroup.PrinterName
and lPrinterDevice.Printer.PrinterSetup.BinName:= PrinterGroup.TrayName;
but the values do not match.
If I run this same code using a standard windows .exe I have no issues.
Do you have any idea why this would be happening under a service.
procedure TPrintFile.ExecutePrint;
var
lArchiveReader: TppArchiveReader;
lPrinterDevice: TppPrinterDevice;
begin
try
if not FileExists(RAFFileName) then
raise EInsightRAFFileDoesNotExist.Create(RAFFileName);
FPrinterGroup:=
PrintServerPrint.AddPrinterGroupIfNotExists(Self.CompanyDatabaseName,
Self.WhseId, Self.UserId, Self.DocumentClassId);
lArchiveReader:= TppArchiveReader.Create(nil);
try
lPrinterDevice:= TppPrinterDevice.Create(nil);
try
lArchiveReader.ShowPrintDialog:= False;
lArchiveReader.SuppressOutline:= True;
lArchiveReader.SavePrinterSetup:= False;
lArchiveReader.ShowCancelDialog:= False;
lArchiveReader.DeviceType:= 'Printer';
lArchiveReader.AllowPrintToFile:= False;
lArchiveReader.ArchiveFileName:= RafFileName;
lPrinterDevice.Publisher:= lArchiveReader.Publisher;
// Assignment of printer routing info happens here.
lPrinterDevice.Printer.DocumentName:= DocTemp.DocumentName;
lPrinterDevice.Printer.PrinterName:= PrinterGroup.PrinterName;
lPrinterDevice.Printer.PrinterSetup.BinName:= PrinterGroup.TrayName;
lPrinterDevice.Printer.PrinterSetup.Copies:= DocTemp.Copies;
lPrinterDevice.Printer.PrinterSetUp.Duplex:= DocTemp.DuplexType;
LogNTEventSilent(etWarning, ctSuccess,
Format('Before Assignment PrinterName: %s TrayName: %s',
[PrinterGroup.PrinterName,
PrinterGroup.TrayName]));
LogNTEventSilent(etWarning, ctSuccess,
Format('After Assignment PrinterName: %s TrayName: %s',
[lPrinterDevice.Printer.PrinterName,
lPrinterDevice.Printer.PrinterSetUp.BinName]));
lArchiveReader.PrintToDevices;
finally
lPrinterDevice.Free;
end;
finally
lArchiveReader.Free;
end;
SetPrintStatusComplete;
except
on E: Exception do begin
if E is EInsightExceptionBase then
raise
else
raise EMethodException.Create('procedure TPrintFile.ExecutePrint',
E.Message);
end;
end;
end;
problem I am having is the assignment of PrinterName and TrayName does not
"stick" when set in code.
I am writing out the PrinterName and TrayName before and after the
assignment to lPrinterDevice.Printer.PrinterName:= PrinterGroup.PrinterName
and lPrinterDevice.Printer.PrinterSetup.BinName:= PrinterGroup.TrayName;
but the values do not match.
If I run this same code using a standard windows .exe I have no issues.
Do you have any idea why this would be happening under a service.
procedure TPrintFile.ExecutePrint;
var
lArchiveReader: TppArchiveReader;
lPrinterDevice: TppPrinterDevice;
begin
try
if not FileExists(RAFFileName) then
raise EInsightRAFFileDoesNotExist.Create(RAFFileName);
FPrinterGroup:=
PrintServerPrint.AddPrinterGroupIfNotExists(Self.CompanyDatabaseName,
Self.WhseId, Self.UserId, Self.DocumentClassId);
lArchiveReader:= TppArchiveReader.Create(nil);
try
lPrinterDevice:= TppPrinterDevice.Create(nil);
try
lArchiveReader.ShowPrintDialog:= False;
lArchiveReader.SuppressOutline:= True;
lArchiveReader.SavePrinterSetup:= False;
lArchiveReader.ShowCancelDialog:= False;
lArchiveReader.DeviceType:= 'Printer';
lArchiveReader.AllowPrintToFile:= False;
lArchiveReader.ArchiveFileName:= RafFileName;
lPrinterDevice.Publisher:= lArchiveReader.Publisher;
// Assignment of printer routing info happens here.
lPrinterDevice.Printer.DocumentName:= DocTemp.DocumentName;
lPrinterDevice.Printer.PrinterName:= PrinterGroup.PrinterName;
lPrinterDevice.Printer.PrinterSetup.BinName:= PrinterGroup.TrayName;
lPrinterDevice.Printer.PrinterSetup.Copies:= DocTemp.Copies;
lPrinterDevice.Printer.PrinterSetUp.Duplex:= DocTemp.DuplexType;
LogNTEventSilent(etWarning, ctSuccess,
Format('Before Assignment PrinterName: %s TrayName: %s',
[PrinterGroup.PrinterName,
PrinterGroup.TrayName]));
LogNTEventSilent(etWarning, ctSuccess,
Format('After Assignment PrinterName: %s TrayName: %s',
[lPrinterDevice.Printer.PrinterName,
lPrinterDevice.Printer.PrinterSetUp.BinName]));
lArchiveReader.PrintToDevices;
finally
lPrinterDevice.Free;
end;
finally
lArchiveReader.Free;
end;
SetPrintStatusComplete;
except
on E: Exception do begin
if E is EInsightExceptionBase then
raise
else
raise EMethodException.Create('procedure TPrintFile.ExecutePrint',
E.Message);
end;
end;
end;
This discussion has been closed.
Comments
because the service was running under the LocalSystem ID (which had no
printers installed) whereas when running as an exe it was using the
login (and printers) of the user that had logged onto the computer.
HTH,
Kevin
I had the same problem: the Local System Account - I know it sounds weird -
does not know any printer, unless you install in Windows Print Server.
So you'll have to let your service log in as another account (one who knows
the printers), but in that case, you can't have any interaction with the
desktop anymore. To overcome this, I had to write a small prog that made a
socket connection to my service and that enabled me to show a status window
or change settings. Big advantage: this program can also be used on a remote
machine.
have fun...
Johan Bouduin
Senior Technical Consultant.
____________________________________________
ICSAT NV
tel. +32(0)3 270 90 17
fax. +32(0)3 270 97 89
visit us: http://www.icsat.com
____________________________________________
To iterate is human; to recurse, divine.