将代码跟踪到PDF或PostScript文件中

时间:2011-11-11 21:01:59

标签: pdf pdf-generation tracking postscript

有没有办法跟踪何时打开PDF?也许将一些脚本嵌入到pdf本身中?

我在下面看到了这个问题,我认为javascript的答案是“不”,但我想知道这是否可行。

Google analytics tracking code insert in pdf file

3 个答案:

答案 0 :(得分:12)

PDF标准包括对JavaScript的支持,但正如@Wes Hardaker指出的那样,并非每个PDF阅读器都支持它。但是,有时一些比没有好。

这是Adobe的官方Acrobat JavaScript Scripting Guide。你可能最感兴趣的是doc对象,它有一个名为getURL()的方法。要使用它,您只需致电:

app.doc.getURL('http://www.google.com/');

将该事件绑定到文档的公开事件,并且您有一个跟踪器。我不太熟悉从Adobe Acrobat中创建事件,但从代码中很容易。下面的代码是一个完整的VS2010 C#WinForms应用程序,它使用开源库iTextSharp(5.1.1.0)。它会创建一个PDF并将JavaScript添加到open事件中。

一些注意事项:只要文档访问外部资源,Adobe Acrobat和Reader都会警告用户。大多数其他PDF阅读器可能也会这样做。 这非常烦人,所以仅仅因为这个原因不应该这样做。 我个人并不关心是否有人跟踪我的文件打开,我只是不想每次都会得到提示。其次,重申一下,此代码适用于Adobe Acrobat和Adobe Reader,可能至少可以使用V6,但在其他PDF阅读器中可能有效,也可能无效。第三,没有安全的方法来唯一地识别用户。这样做会要求您创建和存储一些“cookie”,这需要您写入用户的文件系统,这将被视为不安全。这意味着您只能检测打开的数量,而不是唯一的打开数量。第四,这可能在任何地方都不合法。某些司法管辖区要求您在跟踪用户时通知用户,并为他们提供了查看您正在收集的信息的方式。

但是考虑到上述所有情况,我不能仅仅因为我不喜欢而给出答案。

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //File that we will create
            string OutputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Events.pdf");

            //Standard PDF creation setup
            using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (Document doc = new Document(PageSize.LETTER))
                {
                    using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
                    {
                        //Open our document for writing
                        doc.Open();

                        //Create an action that points to the built-in app.doc object and calls the getURL method on it
                        PdfAction act = PdfAction.JavaScript("app.doc.getURL('http://www.google.com/');", writer);

                        //Set that action as the documents open action
                        writer.SetOpenAction(act);

                        //We need to add some content to this PDF to be valid
                        doc.Add(new Paragraph("Hello"));

                        //Close the document
                        doc.Close();
                    }
                }
            }

            this.Close();
        }
    }
}

答案 1 :(得分:1)

这类技术的问题在于它们永远不会是绝对的。

首先,触发外部事件是违反安全规定的,软件编写者可能不会支持它(或者,至少希望不支持)。

其次,它依赖于网络之类的东西。例如,有人下载并在飞机上离线时读取它会发生什么?你不会收到通知。

第三,有多种方法可以阅读PDF文件。有些人用你可能没听说过的读者阅读它们(我最喜欢的是一个比Adobe的AcroRead更好的Linux应用程序)。

所以,即使你可以做到这一点(我认为你不应该这样做,但这不是你的问题),真正的答案是“不”,但即使软件支持它,它首先仍然不可靠。

答案 2 :(得分:0)

鉴于PostScript 是一种功能完备的编程语言,因此不应该有任何理由不能跟踪它何时被查看/运行。

我认为其中的难点在于找到库(或自己制作函数)来完成日志记录的网络部分。

但是,关于这样的功能,请注意,如果你在失败时仍然可以访问它,那么它可能是最好的。当他们的媒体突然变得不可用时,人们往往会感到不安,这正是如果你在失败时被迫终止会发生的事情。 (你能保证你的日志记录域永远不会改变吗?它总是可用的吗?在用户的情况下没有互联网的情况下会发生什么?)