关于pos小票打印端口的问题(30分)

  • 主题发起人 主题发起人 flyingfly
  • 开始时间 开始时间
F

flyingfly

Unregistered / Unconfirmed
GUEST, unregistred user!
[:)]小票打印直接向LPT1端口写,可以不用打印机驱动打印,但-----如果打印机没有开或者当时没有连接打印机则程序定在那不动啦!有没有能够判断LPT1是否有打印机或者打印没反应自动返回!
我用的是
AssignFile(f,'lpt1');
ReWrite(f);
Write(f,#28#33#1);
writeln(f,'打印日期:'+datetimetostr(now));
closefile(f);
我猜想,是不是有个东西是打印机返回的参数,数据发到LPT1端口的打印机返回个东东。因为没有打印机所以返不了这个东东所以程序定住啦!
 
我在想,能不能有这个样的代码,打印在一个时间段里运行,时间到后自动强制结束,这样就可以避开程序定住啦!
 
没有人能回答吗??
只要作过收款机打印的应该很多人都能遇上这个问题啊~!?
自已顶
 
难。
使用网上的一个驱动可以检测出打印机的状态。
 
什么驱动!
 
我也询问过同样的问题, 关注中.
 
你去盒子上看看,最近在盒子上看到有这个驱动!
主要是因为WIN2K以后都屏蔽了 IN OUT 指令的原因!
 
送你个函数吧
function TestPrinterStatus:byte;
begin
if getversion<$80000000 then
//NT、2000、XP、2003
begin
if not OpenPortTalk then
raise exception.Create('无法加载打印机驱动程序');
result := inportb($379);
ClosePortTalk;
end
else
//windows 95、98、ME
result := GetPrinterStatus;
end;

function GetPrinterStatus:byte;
asm
MOV DX,$379;
IN AL,DX;
end;


要将如下单元加入工程中,并在以上代码use下面的单元,并下载porttalk,把里面的porttalk.sys和porttalk.reg放在可执行文件的目录里,第一次运行时会自动安装到system32目录下,但好象windows 2003要手动安装,然后重启。
unit UnitPortTalk;
interface
uses
Windows, SysUtils, Dialogs,WinSvc;
const
PORTTALK_TYPE = 40000;
{ 32768-65535是保留给用户使用的}
METHOD_BUFFERED = 0;
FILE_ANY_ACCESS = 0;
IOCTL_IOPM_RESTRICT_ALL_ACCESS = PORTTALK_TYPE shl 16 +
$900 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_IOPM_ALLOW_EXCUSIVE_ACCESS = PORTTALK_TYPE shl 16 +
$901 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;

IOCTL_SET_IOPM = PORTTALK_TYPE shl 16 +
$902 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_ENABLE_IOPM_ON_PROCESSID = PORTTALK_TYPE shl 16 +
$903 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_READ_PORT_UCHAR = PORTTALK_TYPE shl 16 +
$904 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
IOCTL_WRITE_PORT_UCHAR = PORTTALK_TYPE shl 16 +
$905 shl 2 +
METHOD_BUFFERED +
FILE_ANY_ACCESS shl 14;
function OpenPortTalk:boolean;
procedure ClosePortTalk;
procedure outportb(PortAddress:word;byte1:byte);
function inportb(PortAddress:word):byte;
function StartPortTalkDriver:boolean;
procedure InstallPortTalkDriver;

var
PortTalk_Handle:THANDLE;
{PortTalk句柄}
implementation

procedure outportb(PortAddress:word;byte1:byte);
var
error:boolean;
BytesReturned:DWORD;
Buffer:array[0..2]of byte;
pBuffer:pword;
begin
pBuffer := pword(@Buffer[0]);
pBuffer^ := PortAddress;
Buffer[2] := byte1;
error := DeviceIoControl(PortTalk_Handle,
Cardinal(IOCTL_WRITE_PORT_UCHAR),
@Buffer,
3,
nil,
0,
BytesReturned,
nil);
if (not error) then
showmessagefmt('从PortTalk输出端口数据时出错:%d',[GetLastError]);
end;

function inportb(PortAddress:word):byte;
var
error:boolean;
BytesReturned:DWORD;
Buffer:array[0..2]of byte;
pBuffer:pword;
begin
pBuffer := pword(@Buffer[0]);
pBuffer^ := PortAddress;
error := DeviceIoControl(PortTalk_Handle,
cardinal(IOCTL_READ_PORT_UCHAR),
@Buffer,
2,
@Buffer,
1,
BytesReturned,
nil);
if (not error) then
showmessagefmt('从PortTalk输入端口数据时出错:%d',[GetLastError]);
result:=Buffer[0];
end;

function OpenPortTalk:boolean;
begin
{打开PortTalk,如果不能打开,则安装它}
PortTalk_Handle := CreateFile('//./PortTalk',
GENERIC_READ,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(PortTalk_Handle = INVALID_HANDLE_VALUE) then
begin
{启动驱动程序}
StartPortTalkDriver;
{再次打开PortTalk}
PortTalk_Handle := CreateFile('//./PortTalk',
GENERIC_READ,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(PortTalk_Handle = INVALID_HANDLE_VALUE) then
begin
showmessage('PortTalk: 不能存取PortTalk,请确保驱动程序已安装。');
result:=false;
exit;
end;
end;
result:=true;
end;

procedure ClosePortTalk;
begin
CloseHandle(PortTalk_Handle);
end;

function StartPortTalkDriver:boolean;
type
TNewStartService=function (hService: SC_HANDLE;
dwNumServiceArgs: DWORD;
lpServiceArgVectors: PPChar): BOOL;
stdcall;
var
SchSCManager:SC_HANDLE;
schService:SC_HANDLE;
ret:BOOL;
err:DWORD;
begin

{打开Service Control Manager}
SchSCManager := OpenSCManager (nil, { 机器 (nil = 本机) }
nil, { 数据库 (nil = 默认 }
SC_MANAGER_ALL_ACCESS);
{ 访问权 }
if (SchSCManager = 0) then
if (GetLastError = ERROR_ACCESS_DENIED) then
begin
{ 没有权限打开SCM管理,必须是poor用户}
showmessage('PortTalk: 没有权限访问Service Control Manager,'#$D#$A+
'不能安装和启动PortTalk,请使用超级用户来安装。');
result:=false;
exit;
end;

repeat begin
{打开PortTalk服务数据库}
schService := OpenService(SchSCManager, {服务数据库句柄}
'PortTalk', {要启动的服务名}
SERVICE_ALL_ACCESS);
{存取的权限}
if (schService = 0) then
case (GetLastError) of
ERROR_ACCESS_DENIED:
begin
showmessage('PortTalk: 没有权限访问PortTalk服务数据库');
result:=false;
exit;
end;
ERROR_INVALID_NAME:
begin
showmessage('PortTalk: 指定的服务名无效');
result:=false;
exit;
end;
ERROR_SERVICE_DOES_NOT_EXIST:
begin
showmessage('PortTalk: PortTalk驱动程序不存在');
InstallPortTalkDriver;
end;
end;
end until (schService <> 0);
{启动PortTalk驱动程序,如果发生错误,一般是由于PortTalk.SYS不存在。}

ret := TNewStartService(@StartService) (schService, {服务标识}
0, {参数个数}
nil);
{参数}

if (ret) then
//showmessage('PortTalk: PortTalk安装成功!')
else
begin
err := GetLastError;
if (err = ERROR_SERVICE_ALREADY_RUNNING) then
showmessage('PortTalk: PortTalk已经安装')
else
begin
showmessage('PortTalk: 启动PortTalk时发生未知错误。'+#$D#$A+
'PortTalk.SYS没有放入/System32/Drivers目录吗?');
result:=false;
exit;
end;
end;

{关闭Service Control Manager}
CloseServiceHandle (schService);
result:=TRUE;
end;

procedure InstallPortTalkDriver;
var
SchSCManager:SC_HANDLE;
schService:SC_HANDLE;
err:DWORD;
DriverFileName:array[0..79]of CHAR;
begin
if (GetSystemDirectory(DriverFileName, 55)=0) then
begin
showmessage('PortTalk: 取System目录出错');
exit;
end;

{加入驱动程序文件名}
lstrcat(DriverFileName,'/Drivers/PortTalk.sys');
showmessagefmt('PortTalk: 拷贝驱动程序到%s',[DriverFileName]);
{拷贝驱动程序到System32/drivers目录,如果出错,一般是因为文件不存在。}
if (not CopyFile('PortTalk.sys', DriverFileName, FALSE)) then
begin
showmessagefmt('PortTalk: 拷贝驱动程序到以下位置出错:%s'+#$D#$A+
'请手工拷贝到system32/driver目录',
[DriverFileName]);
exit;
end;

{打开Service Control Manager}
SchSCManager := OpenSCManager (nil, { 机器 (nil = 本机) }
nil, { 数据库 (nil = 默认 }
SC_MANAGER_ALL_ACCESS);
{ 访问权 }
schService := CreateService (SchSCManager, { SCManager数据库 }
'PortTalk', { 服务个数 }
'PortTalk', { 显示名 }
SERVICE_ALL_ACCESS, { 权限 }
SERVICE_KERNEL_DRIVER, { 服务类别 }
SERVICE_DEMAND_START, { 启动类别 }
SERVICE_ERROR_NORMAL, { 出错控件类别 }
'System32/Drivers/PortTalk.sys', { 服务二进制文件 }
nil, { 加入的组 }
nil, { 标识 }
nil, { 隶属 }
nil, { 本地帐户 }
nil { 密码 }
);
if (schService = 0) then
begin
err := GetLastError;
if (err = ERROR_SERVICE_EXISTS) then
showmessage('PortTalk: 驱动程序不存在。')
else
showmessage('PortTalk:建立服务时发生未知的错误。');
end
else
showmessage('PortTalk: 成功安装!');
{ 关闭Service Control Manager }
CloseServiceHandle (schService);
end;
end.
 
再多说一句,要在打印前使用一下上面的函数,并对那个函数的返回值判断一下,如果打印机状态正常,再打印,如果先打印,再检测是没用的,还会死在那边
 
试试先,先谢谢
说实话真没看懂要具体怎么样作!不过还是要谢谢!
 
多人接受答案了。
 
后退
顶部