Code Monkey home page Code Monkey logo

tuespechkin's Introduction

#TuesPechkin TuesPechkin is a .NET Wrapper for the wkhtmltopdf library.

Things to know

Supported usage

wkhtmltox.dll

The wkhtmltox.dll file and any dependencies it might have (for older versions, 0.11.0-) are not included in the TuesPechkin NuGet package; however, you can bring your own copy of the library or download one of the following NuGet packages that contain the library:

  • TuesPechkin.Wkhtmltox.Win32
  • TuesPechkin.Wkhtmltox.Win64

You must have Visual C++ 2013 runtime installed to use these packages. Otherwise, you will need to download the MingW build of wkhtmltopdf and its dependencies from their website and use that with the library.

Reporting issues

If something doesn't seem right with your converted document, try converting with wkhtmltopdf directly. If you still have the problem, then you will need to take your issue to wkhtmltopdf's issues. Any issues related to visual problems like this will be closed unless the reporter can show that the problem is unique to this library.

Please follow similar guidelines as StackOverflow -- that is, provide any contextual information that you can about your application to help solve the issue.

Submitting pull requests

For 2.0.0 I am wanting to use the 'git flow' style of branching/merging/releasing. If you have a hotfix, please branch off of hotfix. If you are adding something, please branch off of develop. I won't fully re-explain the methodology here.

Usage

The API drastically changed once more for 2.0.0 for the sake of modularity and extensibility. Please read the following sections thoroughly.

1. Choose a deployment

TuesPechkin exposes an 'IDeployment' interface to represent the folder where wkhtmltox.dll resides. These are the officially supported implementations:

  • EmbeddedDeployment - this is an abstract class with two official implementations: the Win32EmbeddedDeployment and Win64EmbeddedDeployment classes, available from NuGet in their own packages. It contains the wkhtmltopdf file(s) and requires another IDeployment instance to tell it where to create the file(s). This is the recommended and easiest deployment to get started with.
  • TempFolderDeployment - this one generates a temp folder based on the base directory of your application, as well as whether you are running in 32 or 64 bit. Recommended for use with any of the EmbeddedDeployment implementations.
  • StaticDeployment - use this one if you really know what you are doing with TuesPechkin and wkhtmltox.dll. It accepts a string path that you define.

2. Choose a toolset

TuesPechkin exposes an IToolset interface to represent a set of functions from the wkhtmltopdf library. There are three officially supported implementations:

  • PdfToolset - Exposes operations from wkhtmltox.dll to convert HTML into PDF
  • ImageToolset - Exposes operations from wkhtmltox.dll to convert HTML into images
  • RemotingToolset<TToolset> - Manages a toolset of type TToolset across an AppDomain boundary. This is necessary for use in IIS-hosted applications.

There is also an abstract class from which you may inherit: NestingToolset. It provides wrapping functionality that is used by RemotingToolset<TToolset>.

3. Choose a converter

TuesPechkin exposes an IConverter interface. An implementation of IConverter properly makes all of the calls to wkhtmltopdf to convert an IDocument instance (which we will cover shortly.) TuesPechkin supplies two implementations:

  • StandardConverter - A converter that may be used in single-threaded applications
  • ThreadSafeConverter - A converter that manages a single background thread and queues document conversions against it. This is necessary for use in multi-threaded applications, including IIS-hosted applications.

4. Define your document

TuesPechkin exposes three interfaces and one attribute that define an HTML document. These are:

  • WkhtmltoxSettingAttribute: an attribute for properties that instructs an IConverter to apply the property's value to the wkhtmltopdf global or object setting with the name passed to the attribute's constructor.
  • ISettings: a token interface whose implementors are implied to have properties decorated with WkhtmltoxSettingAttribute and/or other ISettings properties.
  • IObject: an interface that represents a wkhtmltopdf 'ObjectSettings'. It requires one method to be implemented: byte[] GetData(). All IObject instances are also ISettings instances by inheritance.
  • IDocument: an interface that represents an HTML document. It requires one method to be implemented: IEnumerable<IObject> GetObjects(). All IDocument instances are also ISettings instances by inheritance.

Because TuesPechkin exposes these interfaces/attributes, you are free to write your own implementations that support whichever wkhtmltopdf settings you so desire. If TuesPechkin's included HtmlDocument class and its related classes do not provide support for a setting you want to use, you may then extend them or create your own classes altogether -- this also goes for use cases where you are only setting a handful of properties and you find the included implementations to be too verbose.

The included HtmlToPdfDocument class and its related classes do not supply any default values to wkhtmltopdf.

Here is how an IDocument is to be processed by an IConverter:

  1. A wkhtmltopdf 'GlobalSettings' is created for the document.
  2. The IDocument is recursively crawled for all ISettings and WkhtmltoxSettingAttribute-decorated properties; these properties are applied to the 'GlobalSettings'.
  3. 'GetObjects()' is called on 'IDocument', and for each 'IObject' that is not null, a wkhtmltopdf 'ObjectSettings' is created and that 'IObject' is recursively crawled for all ISettings and WkhtmltoxSettingAttribute-decorated properties; these properties are applied to the 'ObjectSettings'. The 'ObjectSettings' is then added to the converter.

5. Putting it all together

Create a document with options of your choosing.

var document = new HtmlToPdfDocument
{
    GlobalSettings =
    {
        ProduceOutline = true,
        DocumentTitle = "Pretty Websites",
        PaperSize = PaperKind.A4, // Implicit conversion to PechkinPaperSize
        Margins =
        {
            All = 1.375,
            Unit = Unit.Centimeters
		}
	},
    Objects = {
        new ObjectSettings { HtmlText = "<h1>Pretty Websites</h1><p>This might take a bit to convert!</p>" },
        new ObjectSettings { PageUrl = "www.google.com" },
        new ObjectSettings { PageUrl = "www.microsoft.com" },
		new ObjectSettings { PageUrl = "www.github.com" }
    }
};

Convert it in a quick and dirty console application...

IConverter converter =
    new StandardConverter(
        new PdfToolset(
            new Win32EmbeddedDeployment(
                new TempFolderDeployment())));

byte[] result = converter.Convert(document);

...or in a multi-threaded application...

IConverter converter =
    new ThreadSafeConverter(
        new PdfToolset(
            new Win32EmbeddedDeployment(
                new TempFolderDeployment())));

// Keep the converter somewhere static, or as a singleton instance!
// Do NOT run the above code more than once in the application lifecycle!

byte[] result = converter.Convert(document);

...or in an IIS-hosted application.

IConverter converter =
    new ThreadSafeConverter(
        new RemotingToolset<PdfToolset>(
            new Win32EmbeddedDeployment(
                new TempFolderDeployment())));

// Keep the converter somewhere static, or as a singleton instance!
// Do NOT run the above code more than once in the application lifecycle!

byte[] result = converter.Convert(document);

Use the embedded library from the TuesPechkin.Wkhtmltox.Win64 NuGet package instead.

IConverter converter =
    new StandardConverter(
        new PdfToolset(
            new Win64EmbeddedDeployment(
                new TempFolderDeployment())));

byte[] result = converter.Convert(document);

License

This work, "TuesPechkin", is a derivative of "Pechkin" by gmanny (Slava Kolobaev) used under the Creative Commons Attribution 3.0 license. This work is made available under the terms of the Creative Commons Attribution 3.0 license (viewable at http://creativecommons.org/licenses/by/3.0/) by tuespetre (Derek Gray.)

tuespechkin's People

Contributors

ghidello avatar gmanny avatar marcogrcr avatar olivertitze avatar tomap avatar tuespetre avatar wislon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tuespechkin's Issues

Factory.Create Call Running Forever

I'm running:

var pechkin = Factory.Create(new GlobalConfig());

and it's taking 10+ minutes to run (I've placed breakpoints on it and the line immediately following and the breakpoint arrow vanishes for said amount of time). I have yet to come across a case where it actually completes that instruction. When pausing debugger mode and 'disabling my code' it seems to be stuck on this line in the Nuget package regardless of time passed since the initial Create call:

(function(n,t,i){"use strict";function w(t,i){var u,f;if(n.isArray(t)){for(u=t.length-1;u>=0;u--)f=t[u],n.type(t)==="object"||n.type(f)==="string"&&r.transports[f]||(i.log("Invalid transport: "+f+", removing it from the transports list."),t.splice(u,1));t.length===0&&(i.log("No transports remain within the specified transport array."),t=null)}else if(n.type(t)==="object"||r.transports[t]||t==="auto"){if(t==="auto"&&r._.ieVersion<=8)return["longPolling"]}else i.log("Invalid transport: "+t.toString()+"."),t=null;return t}function b(n){return n==="http:"?80:n==="https:"?443:void 0}function l(n,t){return t.match(/:\d+$/)?t:t+":"+b(n)}function k(t,i){var u=this,r=[];u.tryBuffer=function(i){return t.state===n.signalR.connectionState.connecting?(r.push(i),!0):!1};u.drain=function(){if(t.state===n.signalR.connectionState.connected)while(r.length>0)i(r.shift())};u.clear=function(){r=[]}}var f={nojQuery:"jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file.",noTransportOnInit:"No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.",errorOnNegotiate:"Error during negotiation request.",stoppedWhileLoading:"The connection was stopped during page load.",stoppedWhileNegotiating:"The connection was stopped during the negotiate request.",errorParsingNegotiateResponse:"Error parsing negotiate response.",protocolIncompatible:"You are using a version of the client that isn't compatible with the server. Client version {0}, server version {1}.",sendFailed:"Send failed.",parseFailed:"Failed at parsing response: {0}",longPollFailed:"Long polling request failed.",eventSourceFailedToConnect:"EventSource failed to connect.",eventSourceError:"Error raised by EventSource",webSocketClosed:"WebSocket closed.",pingServerFailedInvalidResponse:"Invalid ping response when pinging server: '{0}'.",pingServerFailed:"Failed to ping server.",pingServerFailedStatusCode:"Failed to ping server.  Server responded with status code {0}, stopping the connection.",pingServerFailedParse:"Failed to parse ping server response, stopping the connection.",noConnectionTransport:"Connection is in an invalid state, there is no transport active."};if(typeof n!="function")throw new Error(f.nojQuery);var r,h,s=t.document.readyState==="complete",e=n(t),c="__Negotiate Aborted__",u={onStart:"onStart",onStarting:"onStarting",onReceived:"onReceived",onError:"onError",onConnectionSlow:"onConnectionSlow",onReconnecting:"onReconnecting",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},a=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},o=function(t,i,r){return i===t.state?(t.state=r,n(t).triggerHandler(u.onStateChanged,[{oldState:i,newState:r}]),!0):!1},v=function(n){return n.state===r.connectionState.disconnected},y=function(i){var f=i._.config,e=function(t){n(i).triggerHandler(u.onError,[t])};!f.pingIntervalId&&f.pingInterval&&(i._.pingIntervalId=t.setInterval(function(){r.transports._logic.pingServer(i).fail(e)},f.pingInterval))},p=function(n){var i,u;n._.configuredStopReconnectingTimeout||(u=function(n){n.log("Couldn't reconnect within the configured timeout ("+n.disconnectTimeout+"ms), disconnecting.");n.stop(!1,!1)},n.reconnecting(function(){var n=this;n.state===r.connectionState.reconnecting&&(i=t.setTimeout(function(){u(n)},n.disconnectTimeout))}),n.stateChanged(function(n){n.oldState===r.connectionState.reconnecting&&t.clearTimeout(i)}),n._.configuredStopReconnectingTimeout=!0)};r=function(n,t,i){return new r.fn.init(n,t,i)};r._={defaultContentType:"application/x-www-form-urlencoded; charset=UTF-8",ieVersion:function(){var i,n;return t.navigator.appName==="Microsoft Internet Explorer"&&(n=/MSIE ([0-9]+\.[0-9]+)/.exec(t.navigator.userAgent),n&&(i=t.parseFloat(n[1]))),i}(),error:function(n,t){var i=new Error(n);return i.source=t,i},transportError:function(n,t,r){var u=this.error(n,r);return u.transport=t?t.name:i,u},format:function(){for(var t=arguments[0],n=0;n<arguments.length-1;n++)t=t.replace("{"+n+"}",arguments[n+1]);return t},firefoxMajorVersion:function(n){var t=n.match(/Firefox\/(\d+)/);return!t||!t.length||t.length<2?0:parseInt(t[1],10)}};r.events=u;r.resources=f;r.ajaxDefaults={processData:!0,timeout:null,async:!0,global:!1,cache:!1};r.changeState=o;r.isDisconnecting=v;r.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4};r.hub={start:function(){throw new Error("SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/js'><\/script>.");}};e.load(function(){s=!0});r.fn=r.prototype={init:function(t,i,r){var f=n(this);this.url=t;this.qs=i;this._={connectingMessageBuffer:new k(this,function(n){f.triggerHandler(u.onReceived,[n])}),onFailedTimeoutHandle:null};typeof r=="boolean"&&(this.logging=r)},_parseResponse:function(n){var t=this;return n?t.ajaxDataType==="text"?t.json.parse(n):n:n},json:t.JSON,isCrossDomain:function(i,r){var u;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=r||t.location,u=t.document.createElement("a"),u.href=i,u.protocol+l(u.protocol,u.host)!==r.protocol+l(r.protocol,r.host))},ajaxDataType:"text",contentType:"application/json; charset=UTF-8",logging:!1,state:r.connectionState.disconnected,keepAliveData:{},clientProtocol:"1.3",reconnectDelay:2e3,transportConnectTimeout:0,disconnectTimeout:3e4,keepAliveWarnAt:2/3,start:function(i,h){var l=this,a={pingInterval:3e5,waitForPageLoad:!0,transport:"auto",jsonp:!1},d,v=l._deferral||n.Deferred(),b=t.document.createElement("a"),k,g;if(l._deferral=v,!l.json)throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.");if(n.type(i)==="function"?h=i:n.type(i)==="object"&&(n.extend(a,i),n.type(a.callback)==="function"&&(h=a.callback)),a.transport=w(a.transport,l),!a.transport)throw new Error("SignalR: Invalid transport(s) specified, aborting start.");return(l._.config=a,!s&&a.waitForPageLoad===!0)?(l._.deferredStartHandler=function(){l.start(i,h)},e.bind("load",l._.deferredStartHandler),v.promise()):l.state===r.connectionState.connecting?v.promise():o(l,r.connectionState.disconnected,r.connectionState.connecting)===!1?(v.resolve(l),v.promise()):(p(l),b.href=l.url,b.protocol&&b.protocol!==":"?(l.protocol=b.protocol,l.host=b.host,l.baseUrl=b.protocol+"//"+b.host):(l.protocol=t.document.location.protocol,l.host=t.document.location.host,l.baseUrl=l.protocol+"//"+l.host),l.wsProtocol=l.protocol==="https:"?"wss://":"ws://",a.transport==="auto"&&a.jsonp===!0&&(a.transport="longPolling"),this.isCrossDomain(l.url)&&(l.log("Auto detected cross domain url."),a.transport==="auto"&&(a.transport=["webSockets","longPolling"]),typeof a.withCredentials=="undefined"&&(a.withCredentials=!0),a.jsonp||(a.jsonp=!n.support.cors,a.jsonp&&l.log("Using jsonp because this browser doesn't support CORS.")),l.contentType=r._.defaultContentType),l.withCredentials=a.withCredentials,l.ajaxDataType=a.jsonp?"jsonp":"text",n(l).bind(u.onStart,function(){n.type(h)==="function"&&h.call(l);v.resolve(l)}),d=function(i,s){var w=r._.error(f.noTransportOnInit);if(s=s||0,s>=i.length){n(l).triggerHandler(u.onError,[w]);v.reject(w);l.stop();return}if(l.state!==r.connectionState.disconnected){var c=i[s],h=n.type(c)==="object"?c:r.transports[c],a=!1,p=function(){a||(a=!0,t.clearTimeout(l._.onFailedTimeoutHandle),h.stop(l),d(i,s+1))};if(l.transport=h,c.indexOf("_")===0){d(i,s+1);return}try{l._.onFailedTimeoutHandle=t.setTimeout(function(){l.log(h.name+" timed out when trying to connect.");p()},l.transportConnectTimeout);h.start(l,function(){var i=r._.firefoxMajorVersion(t.navigator.userAgent)>=11,f=!!l.withCredentials&&i;l.state!==r.connectionState.disconnected&&(a||(a=!0,t.clearTimeout(l._.onFailedTimeoutHandle),h.supportsKeepAlive&&l.keepAliveData.activated&&r.transports._logic.monitorKeepAlive(l),y(l),o(l,r.connectionState.connecting,r.connectionState.connected),l._.connectingMessageBuffer.drain(),n(l).triggerHandler(u.onStart),e.bind("unload",function(){l.log("Window unloading, stopping the connection.");l.stop(f)}),i&&e.bind("beforeunload",function(){t.setTimeout(function(){l.stop(f)},0)})))},p)}catch(b){l.log(h.name+" transport threw '"+b.message+"' when attempting to start.");p()}}},k=l.url+"/negotiate",g=function(t,i){var e=r._.error(f.errorOnNegotiate,t);n(i).triggerHandler(u.onError,e);v.reject(e);i.stop()},n(l).triggerHandler(u.onStarting),k=r.transports._logic.prepareQueryString(l,k),k=r.transports._logic.addQs(k,{clientProtocol:l.clientProtocol}),l.log("Negotiating with '"+k+"'."),l._.negotiateRequest=n.ajax(n.extend({},n.signalR.ajaxDefaults,{xhrFields:{withCredentials:l.withCredentials},url:k,type:"GET",contentType:l.contentType,data:{},dataType:l.ajaxDataType,error:function(n,t){t!==c?g(n,l):v.reject(r._.error(f.stoppedWhileNegotiating))},success:function(t){var i,e,h,o=[],s=[];try{i=l._parseResponse(t)}catch(c){g(r._.error(f.errorParsingNegotiateResponse,c),l);return}if(e=l.keepAliveData,l.appRelativeUrl=i.Url,l.id=i.ConnectionId,l.token=i.ConnectionToken,l.webSocketServerUrl=i.WebSocketServerUrl,l.disconnectTimeout=i.DisconnectTimeout*1e3,l.transportConnectTimeout=l.transportConnectTimeout+i.TransportConnectTimeout*1e3,i.KeepAliveTimeout?(e.activated=!0,e.timeout=i.KeepAliveTimeout*1e3,e.timeoutWarning=e.timeout*l.keepAliveWarnAt,e.checkInterval=(e.timeout-e.timeoutWarning)/3):e.activated=!1,!i.ProtocolVersion||i.ProtocolVersion!==l.clientProtocol){h=r._.error(r._.format(f.protocolIncompatible,l.clientProtocol,i.ProtocolVersion));n(l).triggerHandler(u.onError,[h]);v.reject(h);return}n.each(r.transports,function(n){if(n==="webSockets"&&!i.TryWebSockets)return!0;s.push(n)});n.isArray(a.transport)?n.each(a.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,s)>=0)&&o.push(n.type(t)==="string"?""+t:t)}):n.type(a.transport)==="object"||n.inArray(a.transport,s)>=0?o.push(a.transport):o=s;d(o)}})),v.promise())},starting:function(t){var i=this;return n(i).bind(u.onStarting,function(){t.call(i)}),i},send:function(n){var t=this;if(t.state===r.connectionState.disconnected)throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()");if(t.state===r.connectionState.connecting)throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.");return t.transport.send(t,n),t},received:function(t){var i=this;return n(i).bind(u.onReceived,function(n,r){i._.connectingMessageBuffer.tryBuffer(r)||t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(u.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(u.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(u.onDisconnect,function(){t.call(i)}),i},connectionSlow:function(t){var i=this;return n(i).bind(u.onConnectionSlow,function(){t.call(i)}),i},reconnecting:function(t){var i=this;return n(i).bind(u.onReconnecting,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(u.onReconnect,function(){t.call(i)}),i},stop:function(i,h){var l=this,a=l._deferral;if(l._.deferredStartHandler&&e.unbind("load",l._.deferredStartHandler),delete l._deferral,delete l._.config,delete l._.deferredStartHandler,!s&&(!l._.config||l._.config.waitForPageLoad===!0)){l.log("Stopping connection prior to negotiate.");a&&a.reject(r._.error(f.stoppedWhileLoading));return}if(l.state!==r.connectionState.disconnected){try{l.log("Stopping connection.");t.clearTimeout(l._.onFailedTimeoutHandle);t.clearInterval(l._.pingIntervalId);l.transport&&(h!==!1&&l.transport.abort(l,i),l.transport.supportsKeepAlive&&l.keepAliveData.activated&&r.transports._logic.stopMonitoringKeepAlive(l),l.transport.stop(l),l.transport=null);l._.negotiateRequest&&(l._.negotiateRequest.abort(c),delete l._.negotiateRequest);n(l).triggerHandler(u.onDisconnect);delete l.messageId;delete l.groupsToken;delete l.id;delete l._.pingIntervalId;l._.connectingMessageBuffer.clear()}finally{o(l,l.state,r.connectionState.disconnected)}return l}},log:function(n){a(n,this.logging)}};r.fn.init.prototype=r.fn;r.noConflict=function(){return n.connection===r&&(n.connection=h),r};n.connection&&(h=n.connection);n.connection=n.signalR=r})(window.jQuery,window),function(n,t){"use strict";function f(u){var e=u.keepAliveData,o,s;u.state===i.connectionState.connected&&(o=new Date,o.setTime(o-e.lastKeepAlive),s=o.getTime(),s>=e.timeout?(u.log("Keep alive timed out.  Notifying transport that connection has been lost."),u.transport.lostConnection(u)):s>=e.timeoutWarning?e.userNotified||(u.log("Keep alive has been missed, connection may be dead/slow."),n(u).triggerHandler(r.onConnectionSlow),e.userNotified=!0):e.userNotified=!1);e.monitoring&&t.setTimeout(function(){f(u)},e.checkInterval)}function o(n){return n.state===i.connectionState.connected||n.state===i.connectionState.reconnecting}function s(n,i){var r=n.indexOf("?")!==-1?"&":"?";return i&&(n+=r+"connectionData="+t.encodeURIComponent(i)),n}var i=n.signalR,r=n.signalR.events,e=n.signalR.changeState,u;i.transports={};u=i.transports._logic={pingServer:function(t){var e,f,r=n.Deferred();return t.transport?(e=t.transport.name==="webSockets"?"":t.baseUrl,f=e+t.appRelativeUrl+"/ping",f=u.prepareQueryString(t,f),n.ajax(n.extend({},n.signalR.ajaxDefaults,{xhrFields:{withCredentials:t.withCredentials},url:f,type:"GET",contentType:t.contentType,data:{},dataType:t.ajaxDataType,success:function(n){var u;try{u=t._parseResponse(n)}catch(f){r.reject(i._.transportError(i.resources.pingServerFailedParse,t.transport,f));t.stop();return}u.Response==="pong"?r.resolve():r.reject(i._.transportError(i._.format(i.resources.pingServerFailedInvalidResponse,n.responseText),t.transport))},error:function(n){n.status===401||n.status===403?(r.reject(i._.transportError(i._.format(i.resources.pingServerFailedStatusCode,n.status),t.transport,n)),t.stop()):r.reject(i._.transportError(i.resources.pingServerFailed,t.transport,n))}}))):r.reject(i._.transportError(i.resources.noConnectionTransport,t.transport)),r.promise()},prepareQueryString:function(n,t){return t=u.addQs(t,n.qs),s(t,n.data)},addQs:function(t,i){var r=t.indexOf("?")!==-1?"&":"?",u;if(!i)return t;if(typeof i=="object")return t+r+n.param(i);if(typeof i=="string")return u=i.charAt(0),(u==="?"||u==="&")&&(r=""),t+r+i;throw new Error("Query string property must be either a string or object.");},getUrl:function(n,i,r,f){var s=i==="webSockets"?"":n.baseUrl,e=s+n.appRelativeUrl,o="transport="+i+"&connectionToken="+t.encodeURIComponent(n.token);return n.groupsToken&&(o+="&groupsToken="+t.encodeURIComponent(n.groupsToken)),r?(e+=f?"/poll":"/reconnect",n.messageId&&(o+="&messageId="+t.encodeURIComponent(n.messageId))):e+="/connect",e+="?"+o,e=u.prepareQueryString(n,e),e+("&tid="+Math.floor(Math.random()*11))},maximizePersistentResponse:function(n){return{MessageId:n.C,Messages:n.M,Initialized:typeof n.S!="undefined"?!0:!1,Disconnect:typeof n.D!="undefined"?!0:!1,ShouldReconnect:typeof n.T!="undefined"?!0:!1,LongPollDelay:n.L,GroupsToken:n.G}},updateGroups:function(n,t){t&&(n.groupsToken=t)},stringifySend:function(n,t){return typeof t=="string"||typeof t=="undefined"||t===null?t:n.json.stringify(t)},ajaxSend:function(f,e){var h=u.stringifySend(f,e),o=f.url+"/send?transport="+f.transport.name+"&connectionToken="+t.encodeURIComponent(f.token),s=function(t,u){n(u).triggerHandler(r.onError,[i._.transportError(i.resources.sendFailed,u.transport,t),e])};return o=u.prepareQueryString(f,o),n.ajax(n.extend({},n.signalR.ajaxDefaults,{xhrFields:{withCredentials:f.withCredentials},url:o,type:f.ajaxDataType==="jsonp"?"GET":"POST",contentType:i._.defaultContentType,dataType:f.ajaxDataType,data:{data:h},success:function(t){var i;if(t){try{i=f._parseResponse(t)}catch(u){s(u,f);f.stop();return}n(f).triggerHandler(r.onReceived,[i])}},error:function(n,t){t!=="abort"&&t!=="parsererror"&&s(n,f)}}))},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var f=i.url+"/abort?transport="+i.transport.name+"&connectionToken="+t.encodeURIComponent(i.token);f=u.prepareQueryString(i,f);n.ajax(n.extend({},n.signalR.ajaxDefaults,{xhrFields:{withCredentials:i.withCredentials},url:f,async:r,timeout:1e3,type:"POST",contentType:i.contentType,dataType:i.ajaxDataType,data:{}}));i.log("Fired ajax abort async = "+r+".")}},tryInitialize:function(n,t){n.Initialized&&t()},processMessages:function(t,i,f){var e,o=n(t);if(t.transport&&t.transport.supportsKeepAlive&&t.keepAliveData.activated&&this.updateKeepAlive(t),i){if(e=this.maximizePersistentResponse(i),e.Disconnect){t.log("Disconnect command received from server.");t.stop(!1,!1);return}this.updateGroups(t,e.GroupsToken);e.MessageId&&(t.messageId=e.MessageId);e.Messages&&(n.each(e.Messages,function(n,t){o.triggerHandler(r.onReceived,[t])}),u.tryInitialize(e,f))}},monitorKeepAlive:function(t){var i=t.keepAliveData,u=this;i.monitoring?t.log("Tried to monitor keep alive but it's already being monitored."):(i.monitoring=!0,u.updateKeepAlive(t),t.keepAliveData.reconnectKeepAliveUpdate=function(){u.updateKeepAlive(t)},n(t).bind(r.onReconnect,t.keepAliveData.reconnectKeepAliveUpdate),t.log("Now monitoring keep alive with a warning timeout of "+i.timeoutWarning+" and a connection lost timeout of "+i.timeout+"."),f(t))},stopMonitoringKeepAlive:function(t){var i=t.keepAliveData;i.monitoring&&(i.monitoring=!1,n(t).unbind(r.onReconnect,t.keepAliveData.reconnectKeepAliveUpdate),t.keepAliveData={},t.log("Stopping the monitoring of the keep alive."))},updateKeepAlive:function(n){n.keepAliveData.lastKeepAlive=new Date},ensureReconnectingState:function(t){return e(t,i.connectionState.connected,i.connectionState.reconnecting)===!0&&n(t).triggerHandler(r.onReconnecting),t.state===i.connectionState.reconnecting},clearReconnectTimeout:function(n){n&&n._.reconnectTimeout&&(t.clearTimeout(n._.reconnectTimeout),delete n._.reconnectTimeout)},reconnect:function(n,r){var u=i.transports[r],f=this;o(n)&&!n._.reconnectTimeout&&(n._.reconnectTimeout=t.setTimeout(function(){u.stop(n);f.ensureReconnectingState(n)&&(n.log(r+" reconnecting."),u.start(n))},n.reconnectDelay))},handleParseFailure:function(t,u,f,e){t.state===i.connectionState.connecting?(t.log("Failed to parse server response while attempting to connect."),e()):(n(t).triggerHandler(r.onError,[i._.transportError(i._.format(i.resources.parseFailed,u),t.transport,f)]),t.stop())},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.webSockets={name:"webSockets",supportsKeepAlive:!0,send:function(n,t){var r=i.stringifySend(n,t);n.socket.send(r)},start:function(e,o,s){var h,c=!1,l=this,a=!o,v=n(e);if(!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,h+=i.getUrl(e,this.name,a),e.log("Connecting to websocket endpoint '"+h+"'."),e.socket=new t.WebSocket(h),e.socket.onopen=function(){c=!0;e.log("Websocket opened.");i.clearReconnectTimeout(e);f(e,r.connectionState.reconnecting,r.connectionState.connected)===!0&&v.triggerHandler(u.onReconnect)},e.socket.onclose=function(t){if(this===e.socket){if(c)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).triggerHandler(u.onError,[r._.transportError(r.resources.webSocketClosed,e.transport,t)]),e.log("Unclean disconnect from websocket: "+t.reason||"[no reason given].")):e.log("Websocket closed.");else{s?s():a&&l.reconnect(e);return}l.reconnect(e)}},e.socket.onmessage=function(t){var r,f=n(e);try{r=e._parseResponse(t.data)}catch(h){i.handleParseFailure(e,t.data,h,s);return}r&&(n.isEmptyObject(r)||r.M?i.processMessages(e,r,o):f.triggerHandler(u.onReceived,[r]))})},reconnect:function(n){i.reconnect(n,this.name)},lostConnection:function(n){this.reconnect(n)},stop:function(n){i.clearReconnectTimeout(n);n.socket&&(n.log("Closing the Websocket."),n.socket.close(),n.socket=null)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",supportsKeepAlive:!0,timeOut:3e3,start:function(e,o,s){var h=this,c=!1,l=n(e),a=!o,v,y;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}v=r.getUrl(e,this.name,a);try{e.log("Attempting to connect to SSE endpoint '"+v+"'.");e.eventSource=new t.EventSource(v)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message+".");s?s():(l.triggerHandler(u.onError,[i._.transportError(i.resources.eventSourceFailedToConnect,e.transport,p)]),a&&h.reconnect(e));return}a&&(y=t.setTimeout(function(){c===!1&&e.eventSource.readyState!==t.EventSource.OPEN&&h.reconnect(e)},h.timeOut));e.eventSource.addEventListener("open",function(){e.log("EventSource connected.");y&&t.clearTimeout(y);r.clearReconnectTimeout(e);c===!1&&(c=!0,f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.triggerHandler(u.onReconnect))},!1);e.eventSource.addEventListener("message",function(n){var t;if(n.data!=="initialized"){try{t=e._parseResponse(n.data)}catch(i){r.handleParseFailure(e,n.data,i,s);return}r.processMessages(e,t,o)}},!1);e.eventSource.addEventListener("error",function(n){if(this===e.eventSource){if(!c){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState+".");n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending."),h.reconnect(e)):(e.log("EventSource error."),l.triggerHandler(u.onError,[i._.transportError(i.resources.eventSourceError,e.transport,n)]))}},!1)},reconnect:function(n){r.reconnect(n,this.name)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){r.clearReconnectTimeout(n);n&&n.eventSource&&(n.log("EventSource calling close()."),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,f=n.signalR.events,e=n.signalR.changeState,i=r.transports._logic,u=function(){var u=null,f=1e3,i=0;return{prevent:function(){r._.ieVersion<=8&&(i===0&&(u=t.setInterval(function(){var t=n("<iframe style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''><\/iframe>");n("body").append(t);t.remove();t=null},f)),i++)},cancel:function(){i===1&&t.clearInterval(u);i>0&&i--}}}();r.transports.foreverFrame={name:"foreverFrame",supportsKeepAlive:!0,iframeClearThreshold:50,start:function(r,f,e){var c=this,s=i.foreverFrame.count+=1,h,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''><\/iframe>");if(t.EventSource){e&&(r.log("This browser supports SSE, skipping Forever Frame."),e());return}u.prevent();h=i.getUrl(r,this.name);h+="&frameId="+s;n("body").append(o);o.prop("src",h);i.foreverFrame.connections[s]=r;r.log("Binding to iframe's readystatechange event.");o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting."),c.reconnect(r))});r.frame=o[0];r.frameId=s;f&&(r.onSuccess=function(){r.log("Iframe transport started.");f();delete r.onSuccess})},reconnect:function(n){var r=this;t.setTimeout(function(){if(n.frame&&i.ensureReconnectingState(n)){var u=n.frame,t=i.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Updating iframe src to '"+t+"'.");u.src=t}},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,u){var f;i.processMessages(t,u,t.onSuccess);t.state===n.signalR.connectionState.connected&&(t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>r.transports.foreverFrame.iframeClearThreshold&&(t.frameMessageCount=0,f=t.frame.contentWindow||t.frame.contentDocument,f&&f.document&&n("body",f.document).empty()))},stop:function(t){var r=null;if(u.cancel(),t.frame){if(t.frame.stop)t.frame.stop();else try{r=t.frame.contentWindow||t.frame.contentDocument;r.document&&r.document.execCommand&&r.document.execCommand("Stop")}catch(f){t.log("Error occured when stopping foreverFrame transport. Message = "+f.message+".")}n(t.frame).remove();delete i.foreverFrame.connections[t.frameId];t.frame=null;t.frameId=null;delete t.frame;delete t.frameId;delete t.onSuccess;delete t.frameMessageCount;t.log("Stopping forever frame.")}},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){e(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).triggerHandler(f.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,e=n.signalR.changeState,f=n.signalR.isDisconnecting,i=r.transports._logic;r.transports.longPolling={name:"longPolling",supportsKeepAlive:!1,reconnectDelay:3e3,start:function(o,s,h){var a=this,v=function(){v=n.noop;o.log("LongPolling connected.");s();h=null},y=function(){return h?(h(),h=null,o.log("LongPolling failed to connect."),!0):!1},c=o._,l=0,p=function(i){t.clearTimeout(c.reconnectTimeoutId);c.reconnectTimeoutId=null;e(i,r.connectionState.reconnecting,r.connectionState.connected)===!0&&(i.log("Raising the reconnect event"),n(i).triggerHandler(u.onReconnect))},w=36e5;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop());o.messageId=null;c.reconnectTimeoutId=null;c.pollTimeoutId=t.setTimeout(function(){(function e(s,h){var d=s.messageId,g=d===null,b=!g,nt=!h,k=i.getUrl(s,a.name,b,nt);f(s)!==!0&&(o.log("Opening long polling request to '"+k+"'."),s.pollXhr=n.ajax(n.extend({},n.signalR.ajaxDefaults,{xhrFields:{withCredentials:o.withCredentials},url:k,type:"GET",dataType:o.ajaxDataType,contentType:o.contentType,success:function(r){var h,w=0,u,a;o.log("Long poll complete.");l=0;try{h=o._parseResponse(r)}catch(b){i.handleParseFailure(s,r,b,y);return}(c.reconnectTimeoutId!==null&&p(s),h&&(u=i.maximizePersistentResponse(h)),i.processMessages(s,h,v),u&&n.type(u.LongPollDelay)==="number"&&(w=u.LongPollDelay),u&&u.Disconnect)||f(s)!==!0&&(a=u&&u.ShouldReconnect,!a||i.ensureReconnectingState(s))&&(w>0?c.pollTimeoutId=t.setTimeout(function(){e(s,a)},w):e(s,a))},error:function(f,h){if(t.clearTimeout(c.reconnectTimeoutId),c.reconnectTimeoutId=null,h==="abort"){o.log("Aborted xhr request.");return}if(!y()){if(l++,o.state!==r.connectionState.reconnecting&&(o.log("An error occurred using longPolling. Status = "+h+".  Response = "+f.responseText+"."),n(s).triggerHandler(u.onError,[r._.transportError(r.resources.longPollFailed,o.transport,f)])),!i.ensureReconnectingState(s))return;c.pollTimeoutId=t.setTimeout(function(){e(s,!0)},a.reconnectDelay)}}})),b&&h===!0&&(c.reconnectTimeoutId=t.setTimeout(function(){p(s)},Math.min(1e3*(Math.pow(2,l)-1),w))))})(o)},250)},lostConnection:function(){throw new Error("Lost Connection not handled for LongPolling");},send:function(n,t){i.ajaxSend(n,t)},stop:function(n){t.clearTimeout(n._.pollTimeoutId);t.clearTimeout(n._.reconnectTimeoutId);delete n._.pollTimeoutId;delete n._.reconnectTimeoutId;n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function u(n){return n+o}function h(n,t,i){for(var f=n.length,u=[],r=0;r<f;r+=1)n.hasOwnProperty(r)&&(u[r]=t.call(i,n[r],r,n));return u}function c(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function f(n){for(var t in n)if(n.hasOwnProperty(t))return!0;return!1}function e(n,t){var i=n._.invocationCallbacks,r,u;f(i)&&n.log("Clearing hub invocation callbacks with error: "+t+".");n._.invocationCallbackId=0;delete n._.invocationCallbacks;n._.invocationCallbacks={};for(u in i)r=i[u],r.method.call(r.scope,{E:t})}function r(n,t){return new r.fn.init(n,t)}function i(t,r){var u={qs:null,logging:!1,useDefaultPath:!0};return n.extend(u,r),(!t||u.useDefaultPath)&&(t=(t||"")+"/signalr"),new i.fn.init(t,u)}var o=".hubProxy",s=n.signalR;r.fn=r.prototype={init:function(n,t){this.state={};this.connection=n;this.hubName=t;this._={callbackMap:{}}},hasSubscriptions:function(){return f(this._.callbackMap)},on:function(t,i){var r=this,f=r._.callbackMap;return t=t.toLowerCase(),f[t]||(f[t]={}),f[t][i]=function(n,t){i.apply(r,t)},n(r).bind(u(t),f[t][i]),r},off:function(t,i){var e=this,o=e._.callbackMap,r;return t=t.toLowerCase(),r=o[t],r&&(r[i]?(n(e).unbind(u(t),r[i]),delete r[i],f(r)||delete o[t]):i||(n(e).unbind(u(t)),delete o[t])),e},invoke:function(t){var i=this,r=i.connection,e=n.makeArray(arguments).slice(1),o=h(e,c),f={H:i.hubName,M:t,A:o,I:r._.invocationCallbackId},u=n.Deferred(),l=function(t){var f=i._maximizeHubResponse(t),o,e;n.extend(i.state,f.State);f.Error?(f.StackTrace&&r.log(f.Error+"\n"+f.StackTrace+"."),o=f.IsHubException?"HubException":"Exception",e=s._.error(f.Error,o),e.data=f.ErrorData,u.rejectWith(i,[e])):u.resolveWith(i,[f.Result])};return r._.invocationCallbacks[r._.invocationCallbackId.toString()]={scope:i,method:l},r._.invocationCallbackId+=1,n.isEmptyObject(i.state)||(f.S=i.state),r.send(f),u.promise()},_maximizeHubResponse:function(n){return{State:n.S,Result:n.R,Id:n.I,IsHubException:n.H,Error:n.E,StackTrace:n.T,ErrorData:n.D}}};r.fn.init.prototype=r.fn;i.fn=i.prototype=n.connection();i.fn.init=function(i,r){var o={qs:null,logging:!1,useDefaultPath:!0},f=this;n.extend(o,r);n.signalR.fn.init.call(f,i,o.qs,o.logging);f.proxies={};f._.invocationCallbackId=0;f._.invocationCallbacks={};f.received(function(t){var i,o,r,e,s,h;t&&(typeof t.I!="undefined"?(r=t.I.toString(),e=f._.invocationCallbacks[r],e&&(f._.invocationCallbacks[r]=null,delete f._.invocationCallbacks[r],e.method.call(e.scope,t))):(i=this._maximizeClientHubInvocation(t),f.log("Triggering client hub event '"+i.Method+"' on hub '"+i.Hub+"'."),s=i.Hub.toLowerCase(),h=i.Method.toLowerCase(),o=this.proxies[s],n.extend(o.state,i.State),n(o).triggerHandler(u(h),[i.Args])))});f.error(function(n,i){var u,r,e;if((!f.transport||f.transport.name!=="webSockets")&&i){try{if(u=t.JSON.parse(i),!u.I)return}catch(o){return}r=u.I;e=f._.invocationCallbacks[r];e.method.call(e.scope,{E:n});f._.invocationCallbacks[r]=null;delete f._.invocationCallbacks[r]}});f.reconnecting(function(){f.transport&&f.transport.name==="webSockets"&&e(f,"Connection started reconnecting before invocation result was received.")});f.disconnected(function(){e(f,"Connection was disconnected before invocation result was received.")})};i.fn._maximizeClientHubInvocation=function(n){return{Hub:n.H,Method:n.M,Args:n.A,State:n.S}};i.fn._registerSubscribedHubs=function(){var t=this;t._subscribedToHubs||(t._subscribedToHubs=!0,t.starting(function(){var i=[];n.each(t.proxies,function(n){this.hasSubscriptions()&&(i.push({name:n}),t.log("Client subscribed to hub '"+n+"'."))});i.length===0&&t.log("No hubs have been subscribed to.  The client will not receive data from hubs.  To fix, declare at least one client side function prior to connection start for each hub you wish to subscribe to.");t.data=t.json.stringify(i)}))};i.fn.createHubProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),this._registerSubscribedHubs(),t};i.fn.init.prototype=i.fn;n.hubConnection=i}(window.jQuery,window),function(n){n.signalR.version="2.0.0"}(window.jQuery);

I'm debugging through VS Premium 2013 and ran it on both IE11.0.9x and Chrome just to see if it made a difference, but it didn't.

Support for the --post argument?

Hi, is there any plan to support the --post argument allowing additional post data to be sent with the webpage request? If not, could you give me any pointers as to how I could approach it? I've had a brief look, but haven't made much progress.
Thanks!

AccessViolationException while converting multiple pages

Using the following code:

        var document = new HtmlToPdfDocument
        {
            GlobalSettings =
            {
                ProduceOutline = true,
                DocumentTitle = "Pretty Pages",
                PaperSize = PaperKind.A4, // Implicit conversion to PechkinPaperSize
                Margins =
                {
                    All = 1.375,
                    Unit = Unit.Centimeters
                }

            },
            Objects = {
                new ObjectSettings { PageUrl = "http://microsoft.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "https://news.ycombinator.com/"},
                new ObjectSettings { PageUrl = "http://yahoo.ca/"},
                new ObjectSettings { PageUrl = "http://msn.ca/"},
                new ObjectSettings { PageUrl = "http://live.ca/"},
                new ObjectSettings { PageUrl = "http://infoq.com/"},
                new ObjectSettings { PageUrl = "http://slashdot.org/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"},
                new ObjectSettings { PageUrl = "http://google.ca/"}
            }
        };

        var converter = Factory.Create();

        var result = converter.Convert(document);
        var timestamp = DateTime.Now.ToString("hhmmss");
        var filename = String.Format("/{0}.pdf", "PrintedPDF" + timestamp);
        var path = this.Server.MapPath(filename);

        System.IO.File.WriteAllBytes(path, result);

        return File(filename, "application/pdf", Server.UrlEncode(filename));

This results in the following exception:

[AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.]
TuesPechkin.SynchronizedDispatcher.Invoke(Func`1 delegate) +218
TuesPechkin.Proxy.Convert(HtmlToPdfDocument document) +76

Anyone else have this issue?

Certain Settings have no effect

I noticed that DocumentColorMode and LoadImages don't do anything (whereas expected behavior is a PDF without images in grayscale). Possibly EnableJavascript as well (I have a noscript html tag which does not show up when EnableJavascript = false). On the other hand toggling PrintBackground does change what is being rendered.

Here are my settings, which creates a color PDF with images,

            var settings = new HtmlToPdfDocument()
            {
                GlobalSettings =
                {
                    ColorMode = GlobalSettings.DocumentColorMode.Grayscale,
                    ProduceOutline = false,
                    PaperSize = PaperKind.Letter,
                    Margins = {
                        All = 0.5,
                        Unit = Unit.Inches
                    }
                }
            };

            var objectSetting = new ObjectSettings()
            {
                LoadSettings =
                {
                    StopSlowScript = true,
                    DebugJavascript = false
                },

                WebSettings = 
                {
                    EnableJavascript = true,
                    PrintBackground = true,
                    LoadImages = false,
                    EnablePlugins = false,
                    EnableIntelligentShrinking = true
                }
            };
            settings.Objects.Add(objectSetting);

Testing with url,
http://stackoverflow.com/questions/9106419/how-to-cancel-getconsumingenumerable-on-blockingcollection

Latest of post version. Apologies if misunderstanding settings.

Cannot use TuesPechkin from Nunit test project

I am unable to run TuesPechkin form a Nunit unit test project, however identical code runs just fine from a windows console application. My theory is that this has to do with Nunit running the tests in a seperate process/appdomain. This smells an awfully lot like #3, however I have an actual error messsage. When I attempt to run the Nunit test I get the following message:

System.MissingMethodException : Constructor on type 'Pechkin.SimplePechkin' not found.
   at System.RuntimeType.CreateInstanceImpl(BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย refย StackCrawlMarkย stackMark)
   at System.Activator.CreateInstance(Typeย type,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes)
   at System.Activator.CreateInstanceFromInternal(Stringย assemblyFile,ย Stringย typeName,ย Booleanย ignoreCase,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย Evidenceย securityInfo)
   at System.Activator.CreateInstanceFrom(Stringย assemblyFile,ย Stringย typeName,ย Booleanย ignoreCase,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย Evidenceย securityInfo)
   at System.AppDomain.CreateInstanceFrom(Stringย assemblyFile,ย Stringย typeName,ย Booleanย ignoreCase,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย Evidenceย securityAttributes)
   at System.AppDomain.InternalCreateInstanceFromWithNoSecurity(Stringย assemblyName,ย Stringย typeName,ย Booleanย ignoreCase,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย Evidenceย securityAttributes)
   at System.AppDomain.InternalCreateInstanceFromWithNoSecurity(Stringย assemblyName,ย Stringย typeName,ย Booleanย ignoreCase,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย Evidenceย securityAttributes)
   at System.Activator.CreateInstanceFrom(AppDomainย domain,ย Stringย assemblyFile,ย Stringย typeName,ย Booleanย ignoreCase,ย BindingFlagsย bindingAttr,ย Binderย binder,ย Object[]ย args,ย CultureInfoย culture,ย Object[]ย activationAttributes,ย Evidenceย securityAttributes)
   at Pechkin.Factory.Create(GlobalConfigย config)
   at NunitTest.TestClass.TestThing() in TestClass.vb: line 8

You can get a copy of the solution exhibiting the issue here: https://bitbucket.org/VoiceOfWisdom/tuespechkintest

Convert hangs only in production server

By the way, thanks for the awesome project.

I've just encountering an issue when I deploy the site to Production. I'm using the latest TuesPeckin 1.0.3 that has a target framework .NET 4.

By the look of things I'm not quite sure whether I need to have an override method InitializeLifetimeService() on Proxy.cs to resolve the issue.

It's rendering quite a difficult form, and locally it takes some time to perform the conversion.

System.Runtime.Remoting.RemotingException: Object '/2a9dcbbb_6d0e_4e3e_8ddc_70f4ce5c49d9/dckkq2eip7snn0ond1fmuiif_18.rem' has been disconnected or does not exist at the server. Server stack trace: at System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject(IMessage msg) at System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage(IMessage msg) Exception rethrown at [0]: at TuesPechkin.SynchronizedDispatcher.Invoke[TResult](Func`1 delegate) at TuesPechkin.Proxy.Convert(HtmlToPdfDocument document)

Any help / assistance would be greatly appreciated.

Use wkhtmltopdf 0.12.1

Just looking to know which version of wkhtmltopdf this wrapper is using. From their downloads page, they said that the Windows version 0.12 is vulnerable to Heartbleed, and would prefer to use 0.12.1 instead.

If the wrapper's not using the most current version, I'd like to know how this can be updated. Otherwise, feel free to close this.

Issue opening created PDF

I'm having an issue getting up and running with the library. The pdf files get generated without error but I can't seem to open them. Every pdf reader tells me that the file is corrupted.
I know that it is not an issue with my html - I used just a few simple <h1> and <p> tags just like in the example in the usage section.

Any thoughts?

Here's the full text of my code:

    IPechkin pechkin = Factory.Create();
    byte[] output = pechkin.Convert("&lt;h1&gt;Pretty Websites$lt;/h1&gt;&lt;p&gt;This             might take a bit to convert!&lt;/p&gt;");


    Response.Clear();

    Response.ClearContent();
    Response.ClearHeaders();

    Response.ContentType = "application/pdf";
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=test.pdf; size={0}", output.Length));
    Response.BinaryWrite(output);

    Response.Flush();
    Response.End();

Site hangs when a second worker process tries to create a PDF

I am using TuesPechkin on multiple websites that are all hosted on the same web server and only 1 of the sites are able to create a PDF. This appears to be because the site gets a lock on wkhtmltox.dll in the Windows/Temp folder as I can reset IIS and have another site successfully generate a PDF, but then none of the other sites work.

I appreciate this could just be a limitation in the wkhtml2pdf library but I think this problem would be solved if there was a wkhtmltox.dll for each website? Would it be better if the dll just got copied into the bin folder of the running application?

SetContentSpacing doesn't appear to work for the footer

The ObjectConfig.Footer.SetContentSpacing method doesn't appear to work, I presume this maps to the --footer-spacing option in wkhtmltopdf. The content and the footer was always squashed together and I had to use CSS in the footer to add the spacing

MVC Authorization issue.

Not able to set HTML Header. MVC 4 App, with Windows authentication enabled. And Anonymous authentication off. Below error is being printed in place of header, But, I am able to access the HTML file via browser.

Error:
HTTP Error 401.2 - Unauthorized
You are not authorized to view this page due to invalid authentication headers.

Code:

HtmlToPdfDocument doc = new HtmlToPdfDocument();
doc.GlobalSettings = new GlobalSettings
{
ProduceOutline = true,
Margins = new MarginSettings { Left = 5, Right = 5, Top = 250, Bottom = 10, Unit = Unit.Millimeters },
PageOffset = 1,
PaperSize = PaperKind.A4,
};
doc.Objects.Add(new ObjectSettings { HtmlText = s, HeaderSettings = new HeaderSettings { HtmlUrl = "http://localhost:3099/Content/Files/XMLFile1.html" }});

var pechkin = Factory.Create();
var pdf = pechkin.Convert(doc);

Simultaneous converts from different threads crash

First of all, I really like this plugin. I think it's one of the best out there and easy to use.

Let me explain my problem that I encountered:
I have an application that uses TuesPechkin converter through a Web Api.
So the DLL itself is in this web api that has the only purpose of converting html to PDF.

In some scenarios, with big HTML files (aprox 7mb - 600 pages of PDF) we get an error if we have more than 1 threads trying to access a converter:
I have this method:

private void CreatePdfDocumentFromHtml(string htmlContent, string filePath)
{
   IPechkin converter = Factory.Create();
   GlobalSettings settings = new GlobalSettings
                {
                    Margins =
                    {
                        Top = 0.8,
                        Bottom = 0.8,
                        Left = 0.6,
                        Right = 0.6,
                        Unit = Unit.Centimeters
                    },
                    ImageDPI = 200,
                    ImageQuality = 400,
                    DPI = 200
                };   
   HtmlToPdfDocument pdfDocument = new HtmlToPdfDocument
                {
                    GlobalSettings = settings,
                    Objects =
                    {
                        new ObjectSettings
                        { 
                            ProduceLocalLinks = true,
                            ProduceForms = true,
                            HtmlText = htmlContent
                        }                    
                    }                
                };

   converter.Begin += converter_Begin;

   //gets stuck in this method while trying to convert on multiple threads
   byte[] pdfDocumentData = converter.Convert(pdfDocument);

   File.WriteAllBytes(filePath, pdfDocumentData);
}

Separately in my class, just for testing purposes:

void converter_Begin(IPechkin converter, int expectedPhaseCount)
{
     var a = 1;
}

I noticed that when I have 2 or more different threads getting here, only the first to begin triggers the Begin event.
I've seen in the source code that there's a LOCK inside there that deals with these scenarios. Problem is that sometimes, when the first thread has finished its work, I think it also deletes the current progress of the converter on the other threads.

So I get the error related to the Garbage collector or something like that:
error

Just so that you know, it works fine when I make only 1 request with a big file (takes about 10 mins)
OR
more requests simultaneously, but with smaller files that finish in about 1-2 minutes per file.

I've made a temporary solution that kinda transforms that method in a locked method that only allows 1 thread at a time, but that could mean having a queue and the browser or the Host Application throws a "Task canceled" error, because of the time taken for the request I think.

Please tell me if you have any ideeas or fixes. Sorry for the long boring post.

file name

ยฟhow can i get the name of the file generate and how can i delete this file of the server memory?

Second conversion causes web site hanging

Hi,

I use tuespechkin in an asp.net web form site. When I only put Pechkin.dll in the bin folder the application can not load wkhtmltox0.dll. So I end up copying all dll to the bin folder. The conversion works the first time I run it. However it will hang the application when I try to do another conversion. I don't get any exception or error message. My thought is because of the unmanaged dll file. My site won't function until I restart www service. So I convert to the following code to see if it will resolve the problem. However the problem still remains. I look at all the issues related to application hanging I don't see anything similar.

Thanks
Lewis

button_click
 Dim trd As Task(Of Byte())
        trd = Task(Of Byte()).Factory.StartNew(AddressOf ThreadTask)
end button_click

 Private Function ThreadTask() As Byte()
                Dim url As String = "<img src='http://maps.google.com/maps/api/staticmap?"

                Dim config As GlobalConfig = New GlobalConfig().SetDocumentTitle("Client") _
                                                          .SetPaperSize(PaperKind.Letter) _
                                                          .SetMargins(New Margins(150, 100, 150, 100)) _
                                                          .SetImageQuality(100)

                Dim converter As IPechkin = New SimplePechkin(config)
                Dim result() As Byte = converter.Convert(url)

                Return result
 End Function

Improve the documentation

The README.md should have tables for the different available settings, their descriptions, and their values.

TuesPechkin not working on azure websites

Not sure if this is related to the plugin or azure websites, but the platform is set to 32 bits and plugin is working on localhost, but on azure websites it consumes all the cpu and the site stop working.

Custom headers missing from version 1.0.3?

Hi.
I used to have the ability to insert page [page] of [toppage] as my header via the following:
ObjectConfig.Header.SetTexts("", "", "page [page] of [topage]").SetFontSize(9);

Is this function no longer available? I need the ability to show a page count.

Mac

SecurityException in Linux

TuesPechkin is installed from nuGet package to ASP. NET MVC4 application.
Application in running under Mono in Linux with mod_mono
Trying to call TuesPechkin causes SecurityException below.
How to run TuesPechkin in Mono ?

Handling exception type SecurityException
Message is Couldn't impersonate token.
IsTerminating is set to True
System.Security.SecurityException: Couldn't impersonate token.
at System.Security.Principal.WindowsImpersonationContext..ctor (IntPtr token) [0x00000] in :0
at System.Security.Principal.WindowsIdentity.Impersonate (IntPtr userToken) [0x00000] in :0
at TuesPechkin.SynchronizedDispatcher.Run () [0x00000] in :0
at System.Threading.Thread.StartInternal () [0x00000] in :0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Security.SecurityException: Couldn't impersonate token.
at System.Security.Principal.WindowsImpersonationContext..ctor (IntPtr token) [0x00000] in :0
at System.Security.Principal.WindowsIdentity.Impersonate (IntPtr userToken) [0x00000] in :0
at TuesPechkin.SynchronizedDispatcher.Run () [0x00000] in :0
at System.Threading.Thread.StartInternal () [0x00000] in :0

Second usage crashing

I know the earlier versions had issues with creating a second instance for conversion, I have read the related bug reports but none seem to resolve the issue for the more recent versions. I have a program using tuespechkin in a .net 3.5 environment converting a html file into a PDF. The program runs successfully on the first pass, and the second instance crashes. As there is no disposal that i am aware of I am wondering if you can point me to where I might have gone wrong in my execution. I know supposedly there might be some issues with ISS pools, but I am unfamiliar with how or why.

I am using version 1.0.3.0 of tuespechkin downloaded from NUget.

calling the function in this fashion:

        IPechkin converter = Factory.Create();

        byte[] returnfile = converter.Convert(result);

Ont the second pass through the converter I receive a 'AccessViolationException was Unhanded by user code' Attempted to read or write protected memory.

The entire issue can be avoided by recycling my IIS pools after each call. . . .

I will see about trying to make some form of test bed for the code as this is part of a very large project using MS SharePoint and ASP.net

Thanks for wasting your time with my issue,

Anthony

Supplying HTML to footer/header

Hi,

I've noticed the oc.Footer.SetHtmlContent(string htmlUri) way of having an HTML footer/header on Pechkin, i'm in the process of trying this out.

However, is it possible to supply the HTML directly instead of supplying an html file that contains the code?

Thanks

multiple objects in one conversion issue, only last page renders

I was having trouble getting the multiple objects in one conversion working so I pulled in the code from the readme sample (with a few modifications like changing from pageurl to htmltext).

byte[] pdfContent = null;
var document = new HtmlToPdfDocument
{
    GlobalSettings =
    {
        ProduceOutline = true,
        DocumentTitle = "Pretty Websites",
        PaperSize = PaperKind.A4, // Implicit conversion to PechkinPaperSize
        Margins =
        {
            All = 1.375,
            Unit = Unit.Centimeters
        }
    },
    Objects = {
        new ObjectSettings { HtmlText = "<h1>1Pretty Websites</h1><p>This might take a bit to convert!</p>" },
        new ObjectSettings { HtmlText = "<h1>2Pretty Websites</h1><p>This might take a bit to convert!</p>" },
        new ObjectSettings { HtmlText = "<h1>3Pretty Websites</h1><p>This might take a bit to convert!</p>" },
        new ObjectSettings { HtmlText = "<h1>4Pretty Websites</h1><p>This might take a bit to convert!</p>" }
    }
};

IPechkin converter = Factory.Create();

converter.Begin += OnBegin;
converter.Error += OnError;
converter.Warning += OnWarning;
converter.PhaseChanged += OnPhase;
converter.ProgressChanged += OnProgress;
converter.Finished += OnFinished;


pdfContent = converter.Convert(document);

However, when this runs I'm getting three blank pages and the last page has the expected content (the one with "4Pretty Websites"

I'm also getting three warnings such as the one below corresponding to the three blank pages.

Failed loading page file:///C:/Users/slpaige/AppData/Local/Temp/wktemp-f0b0c5ba-e83a-4f2c-8cca-862aa54c790c.html (ignored)"

It looks like maybe the html string is being saved in a temporary file that for some reason is no longer available when the conversion runs?

Can't convert google static map to PDF

I am using the following code to convert google static map to PDF. However I get a blank page. Is it possible to do it?

Thanks
Lewis

 Dim Convert As SynchronizedPechkin = New SynchronizedPechkin(
                                                                        New Pechkin.GlobalConfig().SetMargins(300, 100, 150, 100).SetDocumentTitle("Map").SetCopyCount(1).SetImageQuality(100).SetPaperSize(System.Drawing.Printing.PaperKind.Letter))

                                        Dim result() As Byte = Convert.Convert(New Uri("http://maps.google.com/maps/api/staticmap?center=56.9550198,24.1191180&zoom=13&size=280x200&maptype=roadmap&sensor=false&markers=color:red%7Ccolor:red%7Clabel:C%7C56.9550198,24.1191180"))

UserStyleSheet option doesn't work

In case of specifying UserStyleSheet - it doesn't work at all. Everything works correctly on native wkhtmltopdf binaries with following command: wkhtmltopdf.exe file.htm --user-style-sheet file:///D:/temp/wkhtmltopdf/bin/Site.css out.pdf But TuesPechkin ignores the same URI to CSS file.

Issue using copyright symbol

Hi,

Have you guys seen issues with the copyright symbol?

We are converting an HTML page into a PDF. The html page is a report that has a disclaimer at the bottom. The disclaimer contains copyright information which uses the copyright symbol in several places.

For some reason, when the conversion takes place from HTML to PDF, I end up with the copyright symbol and an extra character attached before the symbol. I've attached an image showing what is happening. This isn't an extra space or anything.

copyright-issue

Even if i add an extra letter before the copyright, that extra character still shows up. I've also tried using different ways to get the copyright in the HTML document, to no avail.

Do you have any suggestions around this issue?

Thanks,

Thiago S.

Hanging on the Convert method on a website running locally

I have a website in IIS on my local machine that I use for
development, it's set up as a virtual directory. A few times a day it is hanging on the Convert method, the image below shows all the threads stuck on that method call.
stuck threads. I can't get any concrete replications steps, it just seems to stop working after a while. I've just done a test now and managed to download about 10-15 PDFs before it hung.

We have 2 versions of this site running on a web server, both of which are working fine and we aren't seeing any problems with it hanging.

Link clickable area is above the link text

I'm fairly certain this is an issue in wkhtmltopdf but raising here for a second opinion.

I added an anchor tag to the footer and when the PDF is generated the clickable area is above the link text. The link works fine when viewing the HTML in my browser. I thought it may have been related to using absolute positioning on the anchor but I got the same issue when replicating the design using tables.

TuesPechkin unable to load DLL 'wkhtmltox.dll'

I've been using TuesPechkin for some time now and today I went to update the nuget package to the new version 2.0.0+ and noticed that Factory.Create() no longer resolved, so I went to read on the GitHub the changes made and noticed it now expects the path to the dll?

IConverter converter =
new ThreadSafeConverter(
new PdfToolset(
new StaticDeployment(DLL_FOLDER_PATH)));
For the past few hours I've tried almost all the paths I can think of, "\bin", "\app_data", "\app_start", etc and I can't seem to find or figure out what it wants for the path and what dll?

I can see the TuesPechkin dll in my bin folder and it was the first path I tried, but I got the following error:

Additional information: Unable to load DLL 'wkhtmltox.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Where is that dll and now can I get it as the library doesn't seem to contain it, I tried installing the TuesPechkin.Wkhtmltox.Win32 package but the dll still is nowhere to be found. Also I am using this in a asp.net website project so I assume that using the following should work for obtaining the path, right?

var path = HttpContext.Current.Server.MapPath(@"~\bin\TuesPechkin.dll");

http://stackoverflow.com/questions/27882601/tuespechkin-unable-to-load-dll-wkhtmltox-dll

Cannot use it in an MVC 2 application hosted under IIS

Hi,

I wrote about my issue in another thread which solved in the meantime, so I decided to create a new one. To summarize, my problem is the following: printing works fine locally in the development server but sometimes it hangs under IIS. I created a stress app that sends multiple requests to IIS to print and I noticed that if I have 20 requests then the whole website crashes and I need to restart IIS for the website to work again. I'm using IIS 7 and Windows 8. I tried the newest version 1.0.3 but I have the same issues as before.

I also created a sample solution which includes an MVC 2 app (this is hosted under IIS) and a console application (which stresses the website for creating PDFs).

https://docs.google.com/file/d/0B5BEdCyqQV_8ak1qXzVzcmZOb2s/edit?pli=1

In help is appreciated.

wkhtmltox.dll path too long exception

Hi,

I'm getting path too long exception in TuesPechkin when setting up the managed assembly, depending on what the temp path and TuesPechkin App Domain base path are . f.ex. "C:\Users\topis\AppData\Local\dftmp\Resources\e09d0f4c-faea-4aea-88b0-d71d0444c159\temp\temp\RoleTemp\TuesPechkin1.0.3.0_x64_CUserstopisAppDataLocaldftmpResourcese09d0f4c-faea-4aea-88b0-d71d0444c159temptempRoleTempTemporary ASP.NET Filesroot9d316a6bdf57b544assemblydl3d7f9823545607c3c_96a2cf01\wkhtmltox.dll"

The temp path is 113 characters, and Tuespechkin adds 192 characters, going over the limit of 260 characters.

Patching TuesPechkin to limit path+filename to 260 characters fixes the problem, but maybe you could revise the path design.

-Tuomo

Support for the --zoom argument

Hi. Thanks so much for TuesPechkin, it's been a godsend to my current project. I could really really do with support for wkhtmltopdf's --zoom parameter though. I don't suppose there's any chance of this making the imminent new release?

currently DocumentColorMode is in reverse order !

Hi, Tuespetre
Firstly thank you for doing such a great job !
I download the release 1.0.3 , After a little test
I found that the option ColorMode is in reverse order.
It will make color pdf when setting ColorMode = DocumentColorMode.Grayscale,
and vice versa. I forked and patched this little problem.

factory.convert hangs with subsequent calls.

environment = asp.net 4.0 / MVC project
web.project and pdfExport.project

issue: subsequent calls to the factory.create(globalConfig()) keep failing and/or are intermittent. Causes w3wp to lockup.

version using: 9.3.3

 code to create convert: 
 public string GeneratePages(List<int> ids)
    {
        var page = url + "/page/getpage/{0}";
        var footer = url + "/page/footer/{0}";
        var savelocation = @"\\somelocation\";
        var globalConfig = new GlobalConfig();

        globalConfig
        .SetOutputFormat(GlobalConfig.OutputFormat.Pdf)
        .SetDocumentTitle("somepage")
        .SetImageQuality(100)
        .SetLosslessCompression(false)
        .SetMaxImageDpi(100)
        .SetOutlineGeneration(false)
        .SetOutputDpi(1200)
        .SetColorMode(true)
        .SetPaperSize(PaperKind.Letter)
        .SetMarginBottom(80)
        .SetMarginTop(40)
        .SetMarginLeft(30)
        .SetMarginRight(30);

        int numberoftasks = ids.Count();
        int completed = 0;

        var tasks = Enumerable.Range(0, ids.Count()).Select(i => new Task(() =>
        {
            var pagepath = string.Format(page, ids[i]);
            var footerpath = string.Format(footer, ids[i]);
            var saveFileName = Path.Combine(savelocation, (ids[i]) + ".pdf");
            //setup
            IPechkin cv = Factory.Create(globalConfig);
            var objectConfig = new ObjectConfig()
                .SetPrintBackground(true)
                .SetIntelligentShrinking(true)
                .SetLoadImages(true);
                            objectConfig.Footer.SetHtmlContent(footerpath).SetFontSize(6).SetContentSpacing(-30);
            objectConfig.Header.SetTexts("", "", "page [page] of [topage]").SetFontSize(9);
            objectConfig.SetPageUri(pagepath);
            //get and save the page
            byte[] pdfbuffer;
   Debug.Write("getting byte array for " + ids[i]);
            pdfbuffer = cv.Convert(objectConfig);
            File.WriteAllBytes(saveFileName, pdfbuffer);
             Debug.Write("completed for: " + ids[i]);
            completed++;
        }));

        Parallel.ForEach(tasks, task => task.Start());

        while (completed < numberoftasks)
        {

            Thread.Sleep(1000);

        }
        return completed.ToString();

    }

my output works the first time only if I kill the w3wp process and rerun the site.
the threads run correctly and i get N number of files back.
The next time i try rerunning it. ie. reload the page withe the same list of IDs.
I just get a hang waiting for the convert method and it just keeps piling up memory against w3wp until it finally kills the server.

here is my debug data.

 getting byte array for 10004
 getting byte array for 10003
 getting byte array for 10000
 getting byte array for 9999
 getting byte array for 10001
 getting byte array for 10002
 'w3wp.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger.Runtime.dll'
 completed for: 10003
 completed for: 10000
 completed for: 10004
 completed for: 9999
 completed for: 10001
 completed for: 10002
 A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.Practices.Unity.Configuration.dll
 getting byte array for 10004
 The thread 'Synchronized Dispatcher Thread #1' (0x2ee4) has exited with code 0 (0x0).
 getting byte array for 9999
 getting byte array for 10001
 getting byte array for 10002
 getting byte array for 10003
 getting byte array for 10000
 The thread '<No Name>' (0x27e0) has exited with code 0 (0x0).
 The thread '<No Name>' (0x1ee0) has exited with code 0 (0x0).
 The thread '<No Name>' (0x21f4) has exited with code 0 (0x0).

Remove hyperlink from pdf output

Is there a way to disable hyperlinks from getting printed to pdf? Say I have an element with a name and href. In my case, the name and href gets outputted to the pdf file. When I was using just the Pechkin project, I did not have this issue.

Size of the PDF output

Hi,

We've noticed that the output PDF we are getting on our application is significantly larger than other PDFs we've produced in the past with similar content and number of pages. We have reports that are generated through Microsoft Word and then saved as PDF documents that are 130 pages and are 2MB in size, while our file generated through this library are 6 pages long and 2MB in size.

Do you know if this is normal, a known issue or if there's something we can do to decrease the size of the output file?

We are generating an HTML page with multiple (5-7) charts from highcharts and other tabular data and then converting that HTML to PDF.

Thanks,

Hanging / Freezes when rebuilding solution on IIS

I'm using the latest version of the library (2.0.0)

The following code works fine.

var document = new HtmlToPdfDocument
            {
                GlobalSettings =
                {
                    ........
                },
                Objects = {
                    new ObjectSettings { PageUrl = "https://www.fb.com" }
                }
            };

            return File(pdfConverter.Convert(document), "application/pdf");

But, after I change the code, for example if I made the url google.com instead of fb.com, IIS/IIS_Express freezes and does not generate the pdf. The only way to resolve this is to restart the web server. Any idea, how I could get rid of this situation??

Hanging on Factory.Create method when running in NUnit test

I'm using the following code to create PDFs. It works fine when running the application on IIS or in the VS development web server.

But, when running the same code in an NUnit test, it hangs when calling Factory.Create.

The same thing happens if running from the NUnit test runner inside VS (even when debugging tests) or from the NUnit console runner.

public void WriteHtmlToPdf(string html, Stream stream, string documentName = null)
{
    GlobalConfig gc = new GlobalConfig();

    gc.SetMargins(new Margins(0,0,0,0))
      .SetPaperSize(PaperKind.A4)
      .SetMaxImageDpi(150)
      .SetImageQuality(95);

    if (documentName != null)
        gc.SetDocumentTitle(documentName);

    using (IPechkin pechkin = Factory.Create(gc))
    {         
        ObjectConfig oc = new ObjectConfig();

        oc.SetCreateExternalLinks(false)
          .SetPrintBackground(true)
          .SetAllowLocalContent(true)
          .SetLoadImages(true);

        // convert document
        byte[] pdfBuf = pechkin.Convert(oc, html);

        stream.Write(pdfBuf, 0, pdfBuf.Length);
    }
}

Stack trace shows where it's hanging:
image

Any ideas what the problem is or how to fix it?

font size output?

Is there a way in either global or document settings to set font size as larger or similar. I am running into an issue where my @media css font size is way bigger than my .pdf output. Both are using the same stylesheet. I have played with the globalSettings(){DPI=1200} but this has no visible effect on output.
I have also seen the fontSize in both header and footer settings and minFontSize in WebSettings. None of these seem to have effect on the rendered output.
Any ideas?

relevant

@media print
{   body 
    {
    color:#000;
    line-height: 1.2;
    font-size: small;
    }

}
var globalsettings = new GlobalSettings()
            { 
                OutputFormat = GlobalSettings.DocumentOutputFormat.PDF,
                PaperSize = PaperKind.Letter,
                DocumentTitle = "xxx",
                ImageQuality = 100,
                UseCompression = false,
                ImageDPI = 150,
                ProduceOutline = false,
                DPI = 1800,
                ColorMode = GlobalSettings.DocumentColorMode.Color,
                Margins =
                {
                    Top = 10,
                    Right = 10,
                    Left = 2,
                    Bottom = 15,
                    Unit = Unit.Millimeters
                }


            };

object settings

  new ObjectSettings()
                           {
                               CountPages = true,
                               PageUrl = pagepath,
                               FooterSettings =
                               {
                                   HtmlUrl = footerpath,
                                   FontSize = 6
                               },
                               HeaderSettings =
                               {
                                   RightText = ("page [page] of [topage]"),
                                   FontSize = 6
                               },
                               LoadSettings =
                               {
                                   Username = username,
                                   Password = password
                               },
                               WebSettings =
                               {
                                   PrintBackground = true, MinimumFontSize = 12
                               }
                           }

File System IO Issue?

I have been working with the latest version of this interface and am very pleased with the results!!!!!

However, I have been having one problem with generating output.

The output file is fine, but if I run the program a second time too soon after the first, the program accessing the pdf generator hangs, and no output results.

I am wondering if the output file system.IO interface is being completely closed and disposed. The hanging appears when I invoke the converter, so I believe it is an internal problem to the interface.

Any thoughts?

[email protected]

PrintMediaType flag not acting as expected in 1.0.3?

To begin with, I'm making the assumption that PrintMediaType = false would be telling the converter to use screen media styles instead of print media styles.

In version 0.9.3.2, this works, properly using the screen media styling (background colors, etc...)

                   GlobalConfig gc = new GlobalConfig();

                    gc.SetPaperOrientation(false)
                      .SetPaperSize(PaperKind.Letter);

                    // create converter and dispose when done
                    using (IPechkin pechkin = Factory.Create(gc))
                    {
                        ObjectConfig oc = new ObjectConfig();

                        oc.SetCreateExternalLinks(false)
                          .SetLoadImages(false)
                          .SetPrintBackground(true)
                          .SetScreenMediaType(true)
                          .SetMinFontSize(8.0)
                          .Footer.SetTexts("", "[page]/[toPage]", "").SetFontSize(8);

                        // convert document
                        pdfContent = pechkin.Convert(oc, stream.ToArray());
                    }

In 1.0.3 using the code snippet below, it looks like the PrintMediaType (and possibly PrintBackground) isn't behaving as expected (backgrounds aren't printing).

                    var document = new HtmlToPdfDocument
                    {
                        GlobalSettings =
                        {
                            PaperSize = PaperKind.Letter,
                            Orientation = TuesPechkin.GlobalSettings.PaperOrientation.Portrait,
                            Margins =
                            {
                                All = 1.375,
                                Unit = Unit.Centimeters
                            }
                        },
                        Objects = {
                            new ObjectSettings { HtmlText = new StreamReader(stream).ReadToEnd() },
                            new ObjectSettings { 
                                WebSettings = 
                                {
                                    PrintMediaType = false,
                                    PrintBackground = true,
                                }
                            },
                        }
                    };

                    IPechkin converter = Factory.Create();
                    pdfContent = converter.Convert(document);

I've looked through the code base, but I didn't see anything glaringly obvious, so was wondering if it might be related to issue #17

Blank pages!

I tried a simple collection like below:

Objects = {
new ObjectSettings { HtmlText = "Hello, world!" },
new ObjectSettings { HtmlText = "Hello, world 3!" },
new ObjectSettings { PageUrl = "www.google.com" },
new ObjectSettings { PageUrl = "www.bing.com" },
new ObjectSettings { HtmlText = "Hello, world 2!" },
}

The objects with PageUrl load fine, but for HtmlText, only the last object ("Hello, world 2!") displays, and all other HtmlText pages are blank.

Cannot add header

I'm having a problem in case I define a header for my reports. The header is not shown at all. I'm using the following code:

var document = new HtmlToPdfDocument
                {
                    GlobalSettings =
                    {
                        ProduceOutline = true, 
                        DocumentTitle = "Report",
                        PaperSize = PaperKind.A4,
                        Orientation = 
                            ContentHasOrientationSetToLandscape(printHtmlContent) ? 
                                GlobalSettings.PaperOrientation.Landscape : GlobalSettings.PaperOrientation.Portrait,
                        Margins =
                        {
                            All = 1.375,
                            Unit = Unit.Centimeters,
                        }
                    },
                    Objects = 
                    {
                        new ObjectSettings 
                        { 
                             HtmlText = printHtmlContent, 
                            FooterSettings = 
                                new FooterSettings 
                                { 
                                    HtmlUrl = "footerUrl"
                                },
                            HeaderSettings =
                                new HeaderSettings
                               { 
                                    HtmlUrl = "headerUrl",
                                }
                        }
                    }
                };

The footer is shown correctly but the main content's top is splitted and no header is showing up. If I print without the header settings then everything works fine. I tried to remove the HtmlText property and the FooterSettings property, in which case the header gets displayed alone.
What am I doing wrong here ?

conversion very slow

conversion works perfectly, but is too slow with my application hosted on a windows server 2008. Any idea how to solve this?.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.