wkhtmltopdf multi page PDF generation process hangs - asp.net

I am attempting to generate a multi-page pdf document in my ASP.Net application using wkhtmltopdf by passing in multiple URLs.
Here is the code that gets called -
Public Shared Function WKHtmlToPdf(ByVal url As String, ByVal OutputDir As String, ByVal OutputFileName As String) As Boolean
Dim blnReturn As Boolean = False
Dim wkhtml As String = HttpContext.Current.Server.MapPath("~/resources/wkhtmltopdf/wkhtmltopdf.exe")
Dim p As New Process()
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.UseShellExecute = False
p.StartInfo.FileName = wkhtml
p.StartInfo.WorkingDirectory = OutputDir
p.StartInfo.Arguments = url & " " & OutputFileName
p.Start()
p.WaitForExit(60000)
Dim returnCode As Integer = p.ExitCode
p.Close()
If returnCode = 0 Then
blnReturn = True
End If
Return blnReturn
End Function
Now the problem I am having is it errors at
p.WaitForExit(60000)
with the following error message.
Process must exit before requested information can be determined.
However, this error only seems to occur when I pass in more than 4 or 5 URLs, it seems random, sometimes its less, sometimes its more. This causes the process to take a long time to generate the PDF and thus error at p.WaitForExit...
I wondered if there some kind of Request limit being hit? I can generate the PDF with as many URLs I need when using the command prompt directly.

The issue is the process is waiting for the exit code which is never returned under normal settings (60 secs).
If you are using the latest version, it supports 'quiet' parameter, this allows the exit code to be returned correctly.
https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
--disable-javascript --quiet --disable-smart-shrinking --print-media-type --margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm --page-size A4 "https://www.google.com" google.pdf

Related

Excel vba download file with random file extension

I am trying to write a code to automatically download files from a website by Excel vba. I know there are plenty of posts regarding this topic but no luck so far. The first few lines of code go like this:
Sub testing()
Dim ie as object
Url _base = "http://www..../download.aspx?id="
Num = cells(1,1).value
Set ie = createobject ("internetexplorer.application")
Ie.visible = true
For i = 1 to num
Url = url _base & i
....
Then I become clueless. The problem is that winhttp seems to only download csv files, and urldownloadtofile requires a solid url path ending with the file extension. However, my case is the link is redirecting to the actual file location (no extension shown), and also the file could be any extension such as pdf, jpg, and doc.
Thanks all in advance!
Ok, editing answer to fold in feedback, three different ways to make an HTTP request and it seems you are looking to trap a redirect which is status codes 300-303, 307-308. Try this and provide feedback as to whether or not you are redirected.
Option Explicit
Private Sub TestGetFileFromWeb()
Call SaveTextToFile(GetFileFromWeb2("http://www.wikipedia.com"), "c:\temp\wikipedia2.txt")
Call SaveTextToFile(GetFileFromWeb3("http://www.wikipedia.com"), "c:\temp\wikipedia3.txt")
'* placed last because it gives "Access Denied" Run-time error '-2147024891 &h80070005
'Call SaveTextToFile(GetFileFromWeb1("http://www.wikipedia.com"), "c:\temp\wikipedia1.txt")
Call SaveTextToFile(GetFileFromWeb1("http://www.bbc.com"), "c:\temp\bbc.txt")
End Sub
Private Function SaveTextToFile(ByRef sText As String, ByVal sFileName As String) As Boolean
'* Requires Tools ->References -> Microsoft Scripting Runtime
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
Dim txtOut As Scripting.TextStream
Set txtOut = fso.CreateTextFile(sFileName, , True)
txtOut.Write sText
txtOut.Close
Set txtOut = Nothing
Set fso = Nothing
SaveTextToFile = True
End Function
Private Function GetFileFromWeb1(ByVal sURL As String) As String
'* Requires Tools->References->Microsoft Xml, v.6.0
Dim xHTTPRequest As MSXML2.XMLHTTP60
Set xHTTPRequest = New MSXML2.XMLHTTP60
xHTTPRequest.Open "GET", sURL, False
xHTTPRequest.Send
Debug.Assert WasRedirected(xHTTPRequest.Status)
GetFileFromWeb1 = xHTTPRequest.ResponseText
End Function
Private Function GetFileFromWeb2(ByVal sURL As String) As String
'* Requires Tools->References->Microsoft WinHTTP Services, version 5.1
Dim oWinHttp As WinHttp.WinHttpRequest
Set oWinHttp = New WinHttp.WinHttpRequest
oWinHttp.Open "GET", sURL, False
oWinHttp.Send
Debug.Assert WasRedirected(oWinHttp.Status)
GetFileFromWeb2 = oWinHttp.ResponseText
End Function
Private Function WasRedirected(ByVal lStatus As Long) As Boolean
'http://qnimate.com/redirection-and-duplicate-content-in-websites/
'There are many types of HTTP redirection.
'
'300 Redirect or Multiple Choices
'301 Redirect or permanent redirect
'302 Redirect or Found or Temporary Redirect
'303 Redirect or See Other
'307 Redirect or Temporary Redirect
'308 Redirect or Permanent Redirect
'HTTP refresh header
WasRedirected = (lStatus = 300 Or lStatus = 301 Or lStatus = 302 Or lStatus = 303 Or lStatus = 307 Or lStatus = 308)
End Function
Private Function GetFileFromWeb3(ByVal sURL As String) As String
'* Requires Tools->References->Microsoft Xml, v.6.0
Dim xHTTPRequest As MSXML2.ServerXMLHTTP60
Set xHTTPRequest = New MSXML2.ServerXMLHTTP60
xHTTPRequest.Open "GET", sURL, False
xHTTPRequest.Send
Debug.Assert WasRedirected(xHTTPRequest.Status)
GetFileFromWeb3 = xHTTPRequest.ResponseText
End Function

Start an Instance of Autodesk Inventor

Am Using Inventor api for customizing inventor documents.Here I use vb.net code for start an instance of the Inventor .my code is
inventorApp = CreateObject("Inventor.Application", "")
inventorApp.Visible = True
it is ok and working fine .but when we open the visual studio run as administrator then the createobject having some error.Any one know any other way to start an instance of Inventor?
Try using the marshal method instead.
Dim m_inventorApp As Inventor.Application
Try ' Try to use active inventor instance
Try
m_inventorApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application")
m_inventorApp.SilentOperation = True
Catch ' If not active, create a new instance of Inventor
Dim inventorAppType As Type = System.Type.GetTypeFromProgID("Inventor.Application")
m_inventorApp = System.Activator.CreateInstance(inventorAppType)
' Must set visible explicitly
m_inventorApp.Visible = True
m_inventorApp.SilentOperation = True
End Try
Catch
'Cant get or create an instance of inventor.
End Try
Private Sub Open_Button_Click()
ThisApplication.SilentOperation = True 'Suppresses the resolve links dialog
Dim myPath As String
myPath = FileName.Text 'Gets the string, FileName, from module 1
Dim Shell As Object
Set Shell = CreateObject("Shell.Application")
Shell.Open (myPath) 'Opens selected file
Resolve_and_Open.Hide 'Hides module
CompareStrings
End Sub
This is to open a sad assembly that needs to resolve links. I'm not sure if this will get around that error, but try using this:
ThisApplication.SilentOperation = True
Either that, or creating a shell and then opening it that way instead of directly.

excuting cmd prompt through asp.net app, with more than one command line

I'm looking to run a command prompt with a "dir" command in my web app and read the response...which I've got working but I need to to do another command first i.e. I need to use a CD to get to the proper directory.
I can get a DIR response and write it to the screen by basically using this link :
http://weblogs.asp.net/guystarbuck/archive/2008/02/06/invoking-cmd-exe-from-net.aspx
or here is the code:
If Not IsPostBack Then
Dim _info As New ProcessStartInfo("cmd", "/C " & "DIR")
' The following commands are needed to redirect the
' standard output. This means that it will be redirected
' to the Process.StandardOutput StreamReader.
_info.RedirectStandardOutput = True
' Set UseShellExecute to false. This tells the process to run
' as a child of the invoking program, instead of on its own.
' This allows us to intercept and redirect the standard output.
_info.UseShellExecute = False
' Set CreateNoWindow to true, to supress the creation of
' a new window
_info.CreateNoWindow = True
' Create a process, assign its ProcessStartInfo and start it
Dim _p As New Process()
_p.StartInfo = _info
_p.Start()
' Capture the results in a string
Dim _processResults As String = _p.StandardOutput.ReadToEnd()
' Close the process to release system resources
_p.Close()
' Return the output stream to the caller
Response.Write(_processResults)
End If
The trouble it's in the wrong directory...how can I do a CD otherdir first?
Anyone know?
Thanks,
You could try with this command concatenation character
Dim _info As New ProcessStartInfo("cmd", "/C C: & CD C:\TEMP & DIR")
Why so complicated? You can use this one-liner:
string[] filePaths = Directory.GetFiles(#"c:\MyDir\", "*.bmp");
to get an array of all files (in this case, all .bmp-files) in the given directory. The extension parameter is optional.

Why 'The local device name is already in use' in asp.net when mapping drive but OK with command line

In command line it works fine:
net USE T: \123.45.67.89\TEST mytestuser /user:MYTESTUSER
But using asp.net, with the following code, the Exception with the following error is always thrown: 'The local device name is already in use' when mapping drive
I have tried disconnecting from all drives first, mapping to a different Drive letter. I have done this from different servers, and to different servers
Is the problem definitely with drive letter?
temp = MapDrive("T", "\\123.45.67.89\TEST", "MYTESTUSER", "mytestuser")
Public Shared Function MapDrive(ByVal DriveLetter As String, ByVal Path As String, ByVal Username As String, ByVal Password As String) As Boolean
Dim ReturnValue As Boolean = False
Dim p As New System.Diagnostics.Process()
p.StartInfo.UseShellExecute = False
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardError = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.FileName = "net.exe"
p.StartInfo.Arguments = " use " & DriveLetter & ": " & Path & " /user:" & Username & " " & Password & " /persistent:yes"
p.Start()
p.WaitForExit()
Dim ErrorMessage As String = p.StandardError.ReadToEnd()
Dim OuputMessage As String = p.StandardOutput.ReadToEnd()
Dim StoreFile As System.IO.Directory
Dim Files As String()
Dim File As String
If ErrorMessage.Length > 0 Then
Throw New Exception("Error:" & ErrorMessage)
Else
ReturnValue = True
End If
Files = StoreFile.GetFiles("T:\FINDTHIS\", "*")
For Each File In Files
HttpContext.Current.Trace.Warn(File)
Next
Return ReturnValue
End Function
Aren't mapped drives particular to the user that is running the net command?
Your asp.net page usually runs under a different identity to the current user's. This means that your code might possibly map the network path successfully the first time you run it. Then when you run it the second time you will get that error.
But then you are looking in vain to delete the mapping for that letter in your cmd window since the drive was not mapped via your user identity (under which your cmd window is running after all)
Then there's also the permissions needed to run the net command, although that might have thrown a different error.

I have path Manipulation issue. The following code is placed in Page_load method of ASPx page + VB

If Request.QueryString("ID") = "" Then
folderDirectory = Global.FileUpload.GetFolderDirectory(Request.QueryString("TFID"))
If Not File.Exists(folderDirectory + fileName) Then
If Not Directory.Exists(folderDirectory) Then
Directory.CreateDirectory(folderDirectory)
End If
Dim bufferSize As Integer = Me.fileUpload.PostedFile.ContentLength
Dim buffer As Byte() = New Byte(bufferSize) {}
' write the byte to disk
Using fs As New FileStream(Path.Combine(folderDirectory, fileName), FileMode.Create)
Dim bytes As Integer = Me.fileUpload.PostedFile.InputStream.Read(buffer, 0, bufferSize)
' write the bytes to the file stream
fs.Write(buffer, 0, bytes)
End Using
Else
CallOnComplete("error", "", "Error uploading '" & fileName & "'. File has been exists!")
Exit Sub
End If
But Fortify scan report for the above sample code shows Path Manipulation issue as high. I Need help to modify above code so that it can pass fortify scan
It is showing me error at folderDirectory
Usually, when your code works inside a web application you don't have the liberty to use the full file system as you do on your local PC. Any kind of 'Path Manipulation' is suspicious.
You should try to recode your works using Server.MapPath method.
Pay particular attention to this warning
For security reasons, the AspEnableParentPaths property has a default value set to FALSE.
Scripts will not have access to the physical directory structure unless AspEnableParentPaths
is set to TRUE.

Resources