C#调用windows API实现 smallpdf客户端程序进行批量压缩

发布时间2018/8/31 10:19:30

下载次数 0 次 访问量188 次


Smallpdf 网站针对PDF文件提供了非常齐全的功能:PDF 与 Word、PPT、Excel、JPG 的相互转化、PDF 的压缩、编辑、合并、分割、解密、加密等功能,用户无需注册即可免费使用。



Smallpdf website provides a very complete function for PDF files: PDF and Word, PPT, Excel, JPG mutual conversion, PDF compression, editing, merging, segmentation, decryption, encryption and other functions, users can use it for free without registration.
But if you don't register for a limited number of PDFs per hour, it's not suitable for us who have a large number of PDFs to compress, so we bought a professional version. The online version provides batch compression, which requires a batch upload waiting for compression before downloading (there are batch uploads, browsers are stuck or no browsers). The method compression has been waiting, and the compression can not be downloaded after success, the speed is only a few dozen K), and the client version of the program does not have the function of mass compression, can only open and compress one article at a time.
In order to understand the above problems, after consideration, ready to use its client compression function for batch compression, although it takes a long time, but do not consider the local network factors, at least very controllable, but it is impossible to manually press each article, so this is the origin of this article.




  主要的原理就是调用WIN API模拟点击,辅助其它的操作完成整个功能,主要的实现就贴主要的代码了,看注释。


[DllImport("User32.dll", EntryPoint = "FindWindow")]
public extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
public struct RECT
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
const int WM_CLOSE = 0x0010;
const int WM_CLICK = 0x00F5;
  enum MouseEventFlag : uint
    Move = 0x0001,
    LeftDown = 0x0002,
    LeftUp = 0x0004,
    RightDown = 0x0008,
    RightUp = 0x0010,
    MiddleDown = 0x0020,
    MiddleUp = 0x0040,
    XDown = 0x0080,
    XUp = 0x0100,
    Wheel = 0x0800,
    VirtualDesk = 0x4000,
    Absolute = 0x8000
static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo);
public static extern int SetCursorPos(int x, int y);
public static void MouseLefClickEvent(int dx, int dy, uint data)
    SetCursorPos(dx, dy);
    mouse_event(MouseEventFlag.LeftDown, dx, dy, data, UIntPtr.Zero);
    mouse_event(MouseEventFlag.LeftUp, dx, dy, data, UIntPtr.Zero);

 var pdfFile = PdfFiles[Index];
    var pdfName = Path.GetFileName(pdfFile);
    System.Diagnostics.Process.Start(SMALLPDFEXE, $"\"{pdfFile}\"");
    while (true)
        IntPtr parentWnd = new IntPtr(0);
        parentWnd = FindWindow(null, pdfName);
        if (!parentWnd.Equals(IntPtr.Zero))
            IntPtr saveWnd = new IntPtr(0);
            IntPtr btnSave = new IntPtr(0);
            while (true)
                SwitchToThisWindow(parentWnd, true);
                RECT rc = new RECT();
                GetWindowRect(parentWnd, ref rc);
                MouseFlag.MouseLefClickEvent(rc.Right - 50, rc.Top + 100, 0);
                saveWnd = FindWindow(null, "Save Document");
                if (!saveWnd.Equals(IntPtr.Zero))
                    btnSave = FindWindowEx(saveWnd, IntPtr.Zero, "Button", "保存(&S)");
                    if (!btnSave.Equals(IntPtr.Zero))
            SendMessage(btnSave, WM_CLICK, IntPtr.Zero, "0");
            bool isCompressed = false;
            int j = 0, checkCount = 60;
            while (j < checkCount)
                string compressPdfName = $"{ Path.GetFileNameWithoutExtension(pdfName)}{COMPRESSED}{Path.GetExtension(pdfFile)}";
                string compressPdfPath = Path.Combine(PDFDIR, compressPdfName);
                if (File.Exists(compressPdfPath))
                    isCompressed = true;
            SendMessage(parentWnd, WM_CLOSE, IntPtr.Zero, "0");
            if (!isCompressed)