I want to be able to have my app check if Adobe Reader is installed.
If it is, I want my program to use it to display the PDF, if not I want to use my free (limited) reader control to display the PDF.
Any suggestions
Edit:
my question seems to be little to broad
So basicly i'm trying to do the following
Try
Dim AcroDisplay As New AxAcroPDFLib.AxAcroPDF
AcroDisplay.Left = 50
AcroDisplay.Top = 50
AcroDisplay.Width = 200
AcroDisplay.Height = 500
me.Controls.Add(AcroDisplay)
MsgBox("Acro Added")
Catch ex As Exception
MsgBox("Acro Not installed")
''Load Alternate PDF viewer (Spire.pdf Free)
End Try
However when Acrobat Isn't installed instead of going to the catch statement it just shows an error "Could not load assembly" and then exits the sub
What i want is that if acrobat control isn't installed, that it wont display and error and instead just load the alternate pdf viewer
is there a way to check for AxAcroPDFLib.AxAcroPDF before attempting to load?
Hopefully this makes things clearer
Edit 2:
After Searching and screwing around i found 2 possible ways i might be able to do this
however both i can't find how to do it in VB.net
First
Look for AxAcroPDFLib.AxAcroPDF in available namespaces
found C# example but i don't know how to change it to Vb.net
C# - How to check if namespace, class or method exists in C#??
Second
Add Unhandled Exception Handler
also found a few examples but none seem to work
Any Chance anyone could direct me to a working example for either (or both) of these options
Manged to fin a working solution, doesn't work how i was originally thinking but it doe work just fine
i used the following code
Dim AdobeSoftwares As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("ADOBE")
If AdobeSoftwares Is Nothing Then
'MessageBox.Show("No Adobe Software")
Dim PdfDisplay As New PdfiumViewer.PdfViewer
PDFControl = "Pdfium"
Else
If Not Array.IndexOf(AdobeSoftwares.GetSubKeyNames, "Acrobat Reader") = -1 Then
'MessageBox.Show("Adobe Reader Installed")
Dim PdfDisplay As New AxAcroPDFLib.AxAcroPDF
PDFControl = "Acrobat"
Else
'MessageBox.Show("Adobe Reader Not Installed")
Dim PdfDisplay As New PdfiumViewer.PdfViewer
PDFControl = "Pdfium"
End If
End If
Then in my display code i just look to see what "PDFControl" is in use and run the relevant code to display in that display
So now if adobe reader is installed, I'll be using its control, and if it isn't I'll be using the free (but less featured) control to display PDF files
So hopefully if anyone else is looking at doing similar to me then they can
Related
I'm trying to check the version of the Windows application the user is running against the version that is on the server to see if the local version needs to be updated. I do this by calling
FileVersionInfo.GetVersionInfo("path to file on server")
and reading the version information. This works fine for what I need, however, when I look at open files on the server from the computer management console, I see many instances of my file open in Read mode. This causes a problem when I need to copy a new version to the server. I first have to close all of the open files before it will let me write to it. Even though they are only open in Read mode, it still makes me close them.
Is there a better way to get the file version from the server? Or is there a way to dispose of the FileInfo variable that I am using so it disconnects?
I have not found a good resolution using FileVersionInfo. And from my research using FileVersionInfo does not release the variable as you would expect so I changed to getting the file information from a PowerShell script. This allows me to dispose the object and release the file as I have tested successfully. So here is the code that gets the information:
Dim server_version As String = ""
Dim invoker As New RunspaceInvoke
Dim command As String = "(Get-Item path_to_file_no_quotes_needed).VersionInfo.FileVersion"
Try
Dim outputObjects As Collection(Of PSObject) = invoker.Invoke(command)
For Each result As PSObject In outputObjects
server_version = result.ToString
Next
Catch ex As Exception
End Try
invoker.dispose
When this is run from my app, I see the file get opened in Read mode on the server but it disappears after about 3 seconds. So I can see the object is being properly disposed. Just FYI, there is no FileVersionInfo.dispose method.
In addition, for this to work you need:
Imports System.Management.Automation
which needs a reference in your project. It can be found in:
C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
In the Shown event I have code that looks like this,
Try
If My.Application.IsNetworkDeployed AndAlso My.Application.Deployment.CheckForUpdate Then
'update available - the update will happen when app is closed
End If
Catch ex As Exception
'error while checking for update or update is corrupt
End Try
I do this so I can provide the user an indication that an update is available.
In the FormClosed event I do,
Try
'see if update is available, and install if it is
If My.Application.IsNetworkDeployed Then
If My.Application.Deployment.CheckForUpdate Then
My.Application.Deployment.Update()
End If
End If
Catch ex As Exception
End Try
I am automating a oft-used paper form by querying the user on a web page, then modifying a base Word document and feeding that modified doc file to the user's browser for hand-off to Word.
The code is Visual Basic, and I am using the Microsoft.Office.Interop module to manipulate the document by manipulating Word. Works fine on the development system (Visual Studio 2015) but not on the production server (IIS 8.5).
Both the Documents.Open() call and the doc.SaveAs() call fail with Message="Command failed" Source="Microsoft Word" HResult=0x800A1066
Things I've tried:
Added debugging out the whazoo: Single-stepping is not an option on the production machine, so I pinpointed the problem lines with debug output.
Googled and found that this problem has been reported as early as 2007, but no viable solutions were reported.
A couple sites mentioned timing issues, so I added several pauses and retries -- none helped.
Some mentioned privileging, so I tried changing file permissions & application pool users -- neither helped.
Enhanced my exception handling reports to show more details and include all inner exceptions. That yielded the magic number 800A1066 which led to many more google hits, but no answers.
Added fall-back code: if you can't open the main document, create a simple one. That's when I found the SaveAs() call also failing.
Dropped back to the development system several times to confirm that yes, the code does still work properly in the right environment.
Greatly condensed sample code does not include fallback logic. My Word document has a number of fields whose names match the XML tokens passed as parameters into this function. saveFields() is an array of those names.
Dim oWord As Word.Application
Dim oDoc As Word.Document
oWord = CreateObject("Word.Application")
oWord.Visible = True
oDoc = oWord.Documents.Open(docName)
Dim ev As String
For i = 0 To saveFields.Length - 1
Try
ev = dataXD.Elements(saveFields(i))(0).Value
Catch
ev = Nothing
End Try
If ev IsNot Nothing Then
Try
Dim field = oDoc.FormFields(saveFields(i))
If field IsNot Nothing Then
If field.Type = Word.WdFieldType.wdFieldFormTextInput Then
field.Result = ev
End If
End If
Catch e As Exception
ErrorOut("Caught exception! " & e.Message)
End Try
End If
Next
...
oDoc.SaveAs2(localDir & filename)
oDoc.Close()
oWord.Quit(0, 0, 0)
The code should generate a modified form (fields filled in with data from the parameters); instead it fails to open, and the fallback code fails to save the new document.
On my dev system the document gets modified as it should, and if I break at the right place and change the right variable, the fallback code runs and generates the alternate document successfully -- but on the production server both paths fail with the same error.
Barring any better answers here, my next steps are to examine and use OpenXML and/or DocX, but making a few changes to the existing code is far preferable to picking a new tool and starting over from scratch.
Unfortunately, Lex Li was absolutely correct, and of course, the link to the reason why is posted on a site my company considers off limits, thus never showed up in my google searches prior to coding this out.
None of the tools I tried were able to handle the form I was trying to automate either -- I needed to fill in named fields and check/uncheck checkboxes, abilities which seemed beyond (or terribly convoluted in) the tools I evaluated ...
Eventually I dug into the document.xml format myself; I developed a function to modify the XML to check a named checkbox, and manipulated the raw document.xml to replace text fields with *-delimited token names. This reduced all of the necessary changes to simple string manipulation -- the rest was trivial.
The tool is 100% home-grown, not dependent upon any non-System libraries and works 100% for this particular form. It is not a generic solution by any stretch, and I suspect the document.xml file will need manual changes if and when the document is ever revised.
But for this particular problem -- it is a solution.
This was the closest I got to a complicated part. This function will check (but not uncheck) a named checkbox from a document.xml if the given condition is true.
Private Shared Function markCheckbox(xmlString As String, cbName As String, checkValue As Boolean) As String
markCheckbox = xmlString
If checkValue Then ' Checkbox needs to be checked, proceed
Dim pos As Integer = markCheckbox.IndexOf("<w:ffData><w:name w:val=""" & cbName & """/>")
If pos > -1 Then ' We have a checkbox
Dim endPos As Integer = markCheckbox.IndexOf("</w:ffData>", pos+1)
Dim cbEnd As Integer = markCheckbox.IndexOf("</w:checkBox>", pos+1)
If endPos > cbEnd AndAlso cbEnd > -1 Then ' Have found the appropriate w:ffData element (pos -> endPos) and the included insert point (cbEnd)
markCheckbox = markCheckbox.Substring(0, cbEnd) & "<w:checked/>" & markCheckbox.Substring(cbEnd)
End If
' Any other logic conditions, return the original XML string unmangled.
End If
End If
End Function
I developed program and tried it on multi PCs, it works perfectly in some of them.
There are 2 PCs with 32 bit, which have given stop working error.
I upgraded one of them into 64 bit, but still has the same problem!
The error appeared at the same moment:
I choose picture from computer then it will shown at picture box
I save data on DB (data include text and picture (ole object))
Then I try add new record and choose new picture the Error message come (program stop working).
program developed using visual basic.net by Visual Studio and access DB
the code of showing picture :
Dim opf As New OpenFileDialog
opf.Filter = "Choose Image(*.JPG;*.PNG;*.GIF)|*.jpg;*.png;*.gif"
If opf.ShowDialog = Windows.Forms.DialogResult.OK Then
nameOfFile = opf.FileName
PicBox.Image = Image.FromFile(opf.FileName)
End If
If it just crashes out of your application, you might want to handle any exceptions. Once you handle the exception you can messagebox the error and it might give you an idea why the application has a problem.
As a guess it might be an issue with 32bit/64bit drivers but best to see why application has the issue first.
Here is the code that #Dennis suggested.
Try
Dim opf As New OpenFileDialog
opf.Filter = "Choose Image(*.JPG;*.PNG;*.GIF)|*.jpg;*.png;*.gif"
If opf.ShowDialog = Windows.Forms.DialogResult.OK Then
nameOfFile = opf.FileName
PicBox.Image = Image.FromFile(opf.FileName)
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
I would guess that the error is more likely in the Save code. If this does not produce a MessageBox then try the same thing on the save code.
If this solves your problem pleas accept #Dennis's answer because it was his idea.
I have a VB WinForms app that prints PDFs using Process.Start, and it has been working fine for ages on Windows 10. Today I go to use it and get the following error message:
"No application is associated with the specified file for this operation"
Nothing has changed to cause this, I have not changed PDF Viewer or uninstalled anything. I can open a PDF by double clicking on it no problems.
I wrote a small console app to replicate the issue and prove this had nothing to do with the WinForms app:
Sub Main()
Dim pi As New Diagnostics.ProcessStartInfo
Dim url As String = "C:\PathToPDF\.pdf"
pi.FileName = url
pi.Verb = "PrintTo"
pi.CreateNoWindow = True
pi.Arguments = """Microsoft Print to PDF"""
pi.UseShellExecute = True
Console.WriteLine(url)
Diagnostics.Process.Start(pi)
Console.ReadKey()
End Sub
The above program replicates the error. I have verified that the file exists and is accessible and tried it with double slashes and single slashes, they give the same error:
"No application is associated with the specified file for this operation".
The same application is working fine on other PCs in the office.
Has anyone else had this happen, and if so how did they fix it?
My PDF viewer is PDFXChange Viewer, and it has been working fine PDFs printed using this method for years. I have not updated the program, and it says in the about page that the last installed updated was in 2016.
Regards.
If I am right, I had the same issue. Maybe you can try it in a slightly other way. I have this in my application and it works fine:
Dim myp As New Process
myp.StartInfo.FileName = filename 'Full path to pdf
myp.Start()
I am working on a vb.net project. I am trying to convert the content of a pdf file to string using acrobat dlls (cannot use other 3 rd party dlls). Below is my code, when I run the program I am getting the following error: "Retrieving the COM class factory for component with CLSID, failed due to the following error: 80040154 Class not registered". I did some research and found out that I have to install the full version of acrobat standard or professional version. Not only that the full version of acrobat must also be installed in all the user machines that the program runs.
Can anyone tell me if this is true and suggest how to fix the class not registered error?
Sub Main()
Dim s As String
Dim sSourceFile As String
sSourceFile = "P:\Report images\DevReports\New Folder\UM-STD-Approval_154.pdf"
Dim oSourceFileInfo As New System.IO.FileInfo(sSourceFile)
Dim st As New AcroPDDoc
st.Open(sSourceFile)
s = GetText(st)
Dim oAcroApp As Acrobat.CAcroApp = New Acrobat.AcroApp
Dim oAcroAvDoc As Acrobat.CAcroAVDoc = New Acrobat.AcroAVDoc
Dim oAcroPDDoc As Object = Nothing
If oAcroAvDoc.Open(sSourceFile, "") Then
'Set PDDoc object and save the file.
oAcroPDDoc = oAcroAvDoc.GetPDDoc()
' oAcroPDDoc.Save(1, sOutputFile)
Else ' Document FAILED to open.
MsgBox("Cannot open ")
End If
oSourceFileInfo = Nothing
oAcroApp.CloseAllDocs()
oAcroPDDoc = Nothing
oAcroAvDoc = Nothing
oAcroApp.Exit()
oAcroApp = Nothing
End Sub
Apologies for the obvious answer but you've kind of answered your own question already.
Adobe Reader is a free application with a very limited interface allowing automation; in practice it's limited to the point where you can display a PDF file and navigate through it (to some extent).
For full features automation (like what I think you are looking for) you will need to install the full Adobe Acrobat. And yes, any system you run this on will also need to have Adobe Acrobat installed.
Now, there are probably libraries out there (including libraries from Adobe or containing Adobe technology inside) that will allow you to embed the functionality you are looking for in your application, but those too will not be free...