如何获取spl文件的页数

时间:2014-08-08 14:01:53

标签: c++ printing spool

我正致力于一个旨在监控打印作业的项目。我将spl和shd文件从假脱机文件夹复制到临时文件夹并尝试解析以获取我想要的数据,例如打印页数,所有者,日期和时间...

我使用以下代码解析假脱机程序spl文件(获取emf文件结构)

#include "stdafx.h"
#include <windows.h>
#include <winspool.h>
#include <stdio.h>
#include <locale.h>   
#include <tchar.h>
#include <iostream>
using namespace std;

BOOL AnalyseFile(const char* pszFileName);

void UPFM(const wchar_t pszInfo[])
{
    wprintf(L"%s\n",pszInfo);
}

 static char* ID_Func[] =
{ 
    "EMF_HEADER", "EMF_POLYBEZIER", /*....*/
};

int main()
{
    setlocale(LC_ALL,"");   

    const char* pszFileName = "~MyTempFolder\\00031.SPL";

    if(!AnalyseFile(pszFileName))
        printf("Analyse File Failed!");
    else
        printf("Analyse File Successed Completed!");

    return 0;
}


BOOL AnalyseFile(const char* pszFileName)
{
    BOOL bRet = FALSE;

    DWORD dwStartPos = 0;
    FILE * f ;
    f = fopen("log.txt", "w");
    FILE* pFile = fopen(pszFileName,"rb");

    if(!pFile)
    {
        fprintf(f,"Open File Failed!");
        return bRet;
    }

    /* =======================Headers================================ */
    DWORD dwTmp = 0;

    fseek(pFile,0,0);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    dwStartPos = dwTmp;

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    long pos = ftell(pFile);

    fseek(pFile,dwTmp,SEEK_SET);

    wchar_t pszInfo[256] = {0};
    pszInfo[0] = L'(';

    WORD wTmp;
    int i;
   for( i = 1;;i++)
    {
        fread(&wTmp,sizeof(wTmp),1,pFile);

        if(!wTmp)
            break;

        memcpy((char*)&pszInfo[i],&wTmp,sizeof(wTmp));
    }
    pszInfo[i] = L')';
    UPFM(pszInfo);

    fseek(pFile,pos,SEEK_SET);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    fseek(pFile,dwTmp,SEEK_SET);

    memset(pszInfo,0,sizeof(wchar_t)*256);
    pszInfo[0] = L'(';
    for(i = 1;;i++)
    {
        fread(&wTmp,sizeof(wTmp),1,pFile);

        if(!wTmp)
            break;

        memcpy((char*)&pszInfo[i],&wTmp,sizeof(wTmp));
    }
    pszInfo[i] = L')';
    UPFM(pszInfo);

    /* ======================== Unknown datas ================================= */
    fseek(pFile,dwStartPos,SEEK_SET);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    fread(&dwTmp,sizeof(DWORD),1,pFile);

    /* ======================== Record datas ================================= */
     DWORD dwTmp2 = 0;
    for(int i=0;;i++)
    {
        pos = ftell(pFile);

        fread(&dwTmp,sizeof(DWORD),1,pFile);

        fread(&dwTmp2,sizeof(DWORD),1,pFile);
        FILE *f;
        f = fopen("log.txt", "a");

        fprintf(f,"index: (%04d)  type: 0x%04X  size: %04d  0x%08X (%s)\n",i,dwTmp,dwTmp2,pos,ID_Func[dwTmp-1]);
        fclose (f);

        if(dwTmp == 0x0E)
        {
            break;
        }

        fseek(pFile,pos+dwTmp2,SEEK_SET);
    }
    fclose (f);
    if(pFile) fclose(pFile);
    bRet = TRUE;

    return bRet;
}

有没有办法用这种方法计算spl文件的页数?

2 个答案:

答案 0 :(得分:0)

要计算页面,您必须计算PAGE标题。

以下是执行此操作的代码的一部分

 SpoolFilename = Path.ChangeExtension(SpoolFilename, ".SPL")

    '\\ Open a binary reader for the spool file
    Dim SpoolFileStream As New System.IO.FileStream(SpoolFilename, FileMode.Open, FileAccess.Read)
    Dim SpoolBinaryReader As New BinaryReader(SpoolFileStream, System.Text.Encoding.UTF8)

    'Read the spooler records and count the total pages
    Dim recNext As EMFMetaRecordHeader = NextHeader(SpoolBinaryReader)
    While recNext.iType <> SpoolerRecordTypes.SRT_EOF
        If recNext.iType = SpoolerRecordTypes.SRT_PAGE Then
            _Pages += 1
        End If
        'SpoolfileReaderPerformaceCounter.Increment()
        Call SkipAHeader(recNext, SpoolBinaryReader)
        recNext = NextHeader(SpoolBinaryReader)
    End While

代码获取文件名,为其打开二进制流,并在标题后读取标题。如果标题代码是SRT_PAGE,则增加页面计数器。

更多详情和来源here

答案 1 :(得分:0)

以下是使用C ++进行操作的方法

struct EMFMetaRecordHeader {
    long Seek;
    SpoolerRecordTypes iType;
    int Size;
};  

if (splfile)
{
    EMFMetaRecordHeader recNext = NextHeader(splfile);
    while (recNext.iType != SpoolerRecordTypes::SRT_EOF)
    {
        if (recNext.iType == SpoolerRecordTypes::SRT_PAGE)
        {
            nPages++;
        }
        recNext = NextHeader(splfile);

    }

    nEmf_record_code = 0;
}

EMFMetaRecordHeader EMFSpoolfileReader::NextHeader(FILE* splfile){
EMFMetaRecordHeader recRet;
recRet.Seek = ftell(splfile);

fread(&recRet.iType, sizeof(int), 1, splfile);
if (feof(splfile))
{
    recRet.iType = SpoolerRecordTypes::SRT_EOF;
    return recRet;
}
fread(&recRet.Size, sizeof(int), 1, splfile);

return recRet;
}

splfile是一个假脱机文件指针

更多详情和来源Django REST docs