在终端服务器中打印原始数据
场景如下:
- 我有一个带有终端服务器的 Windows Server 2008(无域控制器,没有加入域)
- 我有一台更新了 Windows XP SP3 的客户端计算机(.NET 3.0 SP1 和 .NET 4.0)
- 我正在使用 Embarcadero C ++Builder (BCB6)
- 我有一台票据打印机(热敏打印机、POS 打印机、Epson、Zebra 等)。
当我连接到终端服务器时,打印机工作正常。我测试了打印测试页。
当我使用我的软件在本地计算机上的终端服务器中发送原始数据时,出现此错误:
Windows Presentation Foundation terminal server print W has encountered a
problem and needs to close. We are sorry for the inconvenience.
我遵循了此 支持页面但没有运气。
我曾经直接打印到 LPT1:,但是在 Windows Server 2008 中,实现这一点变得越来越困难,因此我们必须更改打印到此类打印机的方式。
这是我正在使用的代码。我在本地进行了测试,它工作正常,但在终端服务器中不起作用:
bool TForm1::RawDataToPrinter(char* szPrinterName, char* lpData, unsigned int dwCount )
{
int BytesWritten;
HANDLE hPrinter;
TDocInfo1 DocInfo;
bool bStatus = false;
int dwJob = 0;
unsigned long dwBytesWritten = 0;
// Open a handle to the printer.
bStatus = OpenPrinter( szPrinterName, &hPrinter, NULL );
if( bStatus )
{
// Fill in the structure with info about this "document."
DocInfo.pDocName = "My Document";
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = "RAW";
// to indicate that the application will be sending document data to the printer.
dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo );
if ( dwJob > 0 )
{
// Start a page.
bStatus = StartPagePrinter( hPrinter );
bStatus = true;
if( bStatus )
{
// Send the data to the printer.
bStatus = WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten );
EndPagePrinter ( hPrinter );
}
// Inform the spooler that the document is ending.
EndDocPrinter( hPrinter );
}
// Close the printer handle.
ClosePrinter( hPrinter );
}
// Check to see if correct number of bytes were written.
if (!bStatus || (dwBytesWritten != dwCount))
bStatus = false;
else
bStatus = true;
return bStatus;
}
我从 Microsoft 支持中的示例复制了此代码。我也尝试将“RAW”更改为“TEXT”,但出现相同的错误。
我尝试了这段代码,因为它使用 GDI 来打印:
long pageline;
char prueba[255];
Printer()->SetPrinter(ListBox1->Items->Strings[ListBox1->ItemIndex].c_str(), "WINSPOOL", "", NULL);
Printer()->BeginDoc();
pageline = 0;
while(pageline < Memo1->Lines->Count)
{
Printer()->Canvas->TextOut(10, (10 + Printer()->Canvas->TextHeight("Hi! There")) * pageline, Memo1->Lines->Strings[pageline]);
pageline++;
}
Printer()->EndDoc();
这是我在 Embarcadero 论坛中找到的一个示例。
我还验证了 TsWpfWrp.exe。我尝试用服务器中的替换它,但它什么也没做,不发送错误,但也不会发送任何数据。
还有另一种方法可以做到这一点吗?我的代码有问题吗?
我感谢任何帮助或见解。
Here is the scenario:
- I have a Windows Server 2008 with Terminal Server (No Domain Controller, No join to Domain)
- I have a client machine with Windows XP SP3 updated (.NET 3.0 SP1 and .NET 4.0)
- I'm Using Embarcadero C++Builder (BCB6)
- I have a ticket printer (Thermal Printer, POS Printer, Epson, Zebra, etc.)
When I connect to the terminal server, the printer works OK. I tested printing a test page.
When I use my software to send the raw data in the terminal server on the local computer, I get this error:
Windows Presentation Foundation terminal server print W has encountered a
problem and needs to close. We are sorry for the inconvenience.
I followed the advice from this support page with no luck.
I used to print directly to LPT1:, but with Windows Server 2008 it's getting harder to make this work, so we have to change the way we print to this kind of printer.
Here is the code that I'm using. I tested locally and it works fine, but in the terminal server doesn't work:
bool TForm1::RawDataToPrinter(char* szPrinterName, char* lpData, unsigned int dwCount )
{
int BytesWritten;
HANDLE hPrinter;
TDocInfo1 DocInfo;
bool bStatus = false;
int dwJob = 0;
unsigned long dwBytesWritten = 0;
// Open a handle to the printer.
bStatus = OpenPrinter( szPrinterName, &hPrinter, NULL );
if( bStatus )
{
// Fill in the structure with info about this "document."
DocInfo.pDocName = "My Document";
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = "RAW";
// to indicate that the application will be sending document data to the printer.
dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo );
if ( dwJob > 0 )
{
// Start a page.
bStatus = StartPagePrinter( hPrinter );
bStatus = true;
if( bStatus )
{
// Send the data to the printer.
bStatus = WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten );
EndPagePrinter ( hPrinter );
}
// Inform the spooler that the document is ending.
EndDocPrinter( hPrinter );
}
// Close the printer handle.
ClosePrinter( hPrinter );
}
// Check to see if correct number of bytes were written.
if (!bStatus || (dwBytesWritten != dwCount))
bStatus = false;
else
bStatus = true;
return bStatus;
}
I copied this code from a example in Microsoft's Support. I also tried changing the "RAW" to "TEXT" but I get the same error.
I tried this code, because it uses the GDI to print:
long pageline;
char prueba[255];
Printer()->SetPrinter(ListBox1->Items->Strings[ListBox1->ItemIndex].c_str(), "WINSPOOL", "", NULL);
Printer()->BeginDoc();
pageline = 0;
while(pageline < Memo1->Lines->Count)
{
Printer()->Canvas->TextOut(10, (10 + Printer()->Canvas->TextHeight("Hi! There")) * pageline, Memo1->Lines->Strings[pageline]);
pageline++;
}
Printer()->EndDoc();
This is a example that I found in the Embarcadero Forum.
I also verified TsWpfWrp.exe. I tried replacing it by the one in the server, but it does nothing, doesn't send the error, but also won't send any data.
There is another way to do this? Do I have something wrong in the code?
I appreciated any help or insight.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我发现问题在于 Easy Print 驱动程序,它期望在 RAW 模式下使用 XPS 规范,但我只发送文本。
我禁用了“轻松打印”以将打印机置于后备模式(类似的),这是终端服务器的位置,首先它查找已安装的驱动程序,然后查找“轻松打印”(这可以在打印机的属性中提前验证)选项)。
现在可以了,谢谢。
I found the problem, is the Easy Print driver, it expect in RAW Mode the XPS specification, but I was sending only text.
I disabled the Easy Print to put the printer in Fallback mode( something like that), this is where the Terminal Server, first it look for the installed driver then for the Easy Print (this can be verified in the properties of the printer in advanced options).
Now it works, thanks.