Save annotations into SQL Server database using adobe javascript - c#

I am having problems trying to save (insert) a .pdf with annotations into a SQL Server database. The database is located inside Visual Studio and I am currently using adobe javascript to save it, but I run into security settings prevent access to this property or method when i clicked the button inside the pdf. I'm using a pdf button field from spire.pdf to try to save into the db and pass the script into pdf javascript action.
So far, i have tried using trusted privilege function, using adbc connection and odbc connection as well as the soap method but it doesn't work and I'm quite lost at what to do or continue next. These methods can be found inside adobe javascript reference as well as api.
PdfPageBase page = pdf.Pages[i];
PdfButtonField button = new PdfButtonField(page, "Save");
button.Bounds = new RectangleF(420, 10, 100, 40);
button.BorderColor = new PdfRGBColor(Color.AliceBlue);
button.BorderStyle = PdfBorderStyle.Solid;
button.ForeColor = new PdfRGBColor(Color.White);
button.Text = "Save";
button.BackColor = new PdfRGBColor(Color.Blue);
button.ToolTip = "Save";
button.Font = new PdfFont(PdfFontFamily.Helvetica, 9f);
pdf.Form.Fields.Add(button);
String script = "var nButton=app.alert({"
+ " cMsg: \"Do you want to save this paper into the database?\","
+ " nIcon: 2,"
+ " nType : 2,"
+ " cTitle: \"Confirm Save?\""
+ "});"
+ "if ( nButton == 4 ) {var myProxy = SOAP.connect(\"http://localhost:57103/test123.svc?wsdl) \"); var testString = (\"This is a test string\"); var result = (myProxy.echoString(testString)); console.println(\"Result is : + result\")};";
PdfJavaScriptAction confirm = new PdfJavaScriptAction(script);
button.Actions.GotFocus = confirm;
The expected result i should get is to be able to save the pdf with annotations into the SQL Server database inside Visual Studio and being able to retrieve it with the annotations. However, the actual result showed the security settings prevent access to this property or method and i cannot proceed to continue.
Would really appreciate some help, thank you! :)

ADBC in Acrobat JavaScript is has been off by default since Acrobat 9. To activate ADBC, create a registry key of type DWORD with the name “bJSEnable” and a value of “true” (1) in the following location:
HKEY_CURRENT_USER\SOFTWARE\Adobe\Adobe Acrobat\VERSION\ADBC
Also the SOAP object was deprecated beginning with Acrobat 8.0. Use Net.SOAP instead.

Related

Network printers ignoring number of copies sent programatically

The setup - a local Windows 10 PC has multiple network printers installed. A GUI C# WinForm application (.NET) is constantly running in the background, and occasionally downloads a PDF file from a predefined URL (read from an *.ini file).
The problem occurs when the said PDF file is printed. Instead of accepting the number of copies sent from the application, the printer keeps printing just one copy of the file.
This is the relevant part of my code:
string webPrinter = "HP LaserJet PCL 6"; // is set in another part of the code
string iniFilePrinter = "hp LaserJet 1320 PCL 5"; // is set in another part of the code - read from the ini file
string dirName = "C:\\mydir";
string newDocName = "mydoc.pdf";
short numCopies = 1;
if(event1 == "event1") { // taken from another part of the code
numCopies = webNumCopies; // taken from another part of the code
} else if(event2 == "event2") {
numCopies = iniNumCopies; // taken from another part of the code - read from the ini file
}
var path = dirName + "\\" + newDocName;
try
{
using (var document = PdfiumViewer.PdfDocument.Load(path))
{
using (var printDocument = document.CreatePrintDocument())
{
System.Drawing.Printing.PrinterSettings settings = new System.Drawing.Printing.PrinterSettings();
string defaultPrinterName = settings.PrinterName;
printDocument.DocumentName = newDocName;
printDocument.PrinterSettings.PrintFileName = newDocName;
printDocument.PrinterSettings.Copies = numCopies;
printDocument.PrintController = new System.Drawing.Printing.StandardPrintController();
printDocument.PrinterSettings.PrinterName = webPrinter;
MessageBox.Show("Before: " + printDocument.PrinterSettings.Copies.ToString() + " --- " + newDocName);
if (!printDocument.PrinterSettings.IsValid)
{
printDocument.PrinterSettings.PrinterName = iniFilePrinter;
if(!printDocument.PrinterSettings.IsValid)
{
printDocument.PrinterSettings.PrinterName = defaultPrinterName;
}
}
MessageBox.Show("After: " + printDocument.PrinterSettings.Copies.ToString() + " --- " + newDocName);
printDocument.Print();
}
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
The exception has never been triggered, and the print succeeds on every single try. Changing the number of copies within if/else also happens when the conditions are met, and the MessageBox.Show() parts of the code do show the expected number of copies (2,3,7, anything but 1, when it's not supposed to be 1) immediatelly before invoking printDocument.Print().
I've also tried printing unrelated documents from various other programs (MS Word, various custom applications, PDF readers and the like), and the number of copies has always been 1. However, software like Google Chrome or FireFox manage to get things printed in the specified number of copies.
I was thinking that there might be something about the printer's setting which makes it ignore the number of copies sent. Based on that assumption, I've checked the settings of all of the printers, and have found that the number of copies is actually set to 1.
If that is indeed the cause of my problem, how can I bypass that setting (without actually changing it), the way that Google Chrome and Firefox seem to be able to do it? I know that I could probably change that limit programmatically (set it to my number of copies, and then change it back to the original value, once the printing has been completed), but that doesn't seem like the proper way of doing it.
EDIT
I've expanded my code by including a print dialog, like this:
PrintDialog printDlg = new PrintDialog();
printDlg.Document = printDocument;
printDlg.AllowSelection = true;
printDlg.AllowSomePages = true;
if (printDlg.ShowDialog() == DialogResult.OK)
{
printDocument.Print();
}
Still, the results are the same - even when the user changes the number of copies within the print dialog, the printer ignores them. The same code was tested on another (local) printer, connected to an unrelated Windows 10 PC, and there the number of copies from the dialog was not ignored.
I've also noticed that the print dialog from my application, and that from notepad.exe are different (image below). Is there a way for me to call up the same print dialog notepad.exe uses? The reason I'd like to do this, is because that one gets the job done (xy number of copies in the print dialog, xy number of copies printed).

Printing copies of document from form textbox

Is there a way to print the number of copies given in a textbox in a C# windows form application?
With my current code the document gets printed the required number of prints, but after the first print there is a dialog that says that the document already is opened and I have to open a copy. When I open this copy, the document prints again, but only if I accept to open the copy. Is there a way to print the document multiple times without getting the dialog of the copy of the document every time?
When the form is filled in correct, I want it to be stored on my hard drive and want it to print the number given in a textbox on a previous form. The value from this textbox is stored in the variable intAantalPoorten.
Thanks a lot!
Regards Bert
CreateWordDocument(#"N:\De wienes\Productieformulieren\Sjablonen\Poortblad.docx", #"N:\De wienes\Productieformulieren\Producties poortbladen\Poortblad " + txtKlantnaam.Text + "-" + txtReferentie.Text + ".docx");
ProcessStartInfo info = new ProcessStartInfo(#"N:\De wienes\Productieformulieren\Producties poortbladen\Poortblad " + txtKlantnaam.Text + "-" + txtReferentie.Text + ".docx");
for (intAAntalPrints = 0; intAAntalPrints <= intAantalPoorten; intAAntalPrints++)
{
info.Verb = "Print";
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(info);
}
You're probably not using the best programming model. The thing you're doing is relying on the windows shell to open the document and invoke the registered verb (as defined by Word in the local registry). This is the most primitive and least functional way to get the job done. For example, there's no way to change which printer you're printing to...or how many copies or which pages, etc.
Instead, there's a rich programming model that Word (and all the Office apps) provide. You can open documents, and print them specifying the number of copies that you want.
To get access to this programming model, you need to reference the .COM interop assembly for Word, which is:
...and the Office Core interop assembly:
Then, it's just a matter of driving Word to do what you want. For example:
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1: Form
{
public Form1( )
{
InitializeComponent( );
}
private void button1_Click( object sender, EventArgs e )
{
//--> assumes the textBox1.Text contains the file to open...
var app = new Microsoft.Office.Interop.Word.Application( );
var doc = app.Documents.Open( textBox1.Text, ReadOnly: true );
doc.PrintOut( Copies: 1 );
doc.Close( );
app.Quit( );
}
}
}
Note that this requires Word to be installed on the local machine. For more information, check out the word object model.

CoolUtils TotalPDFPrinterX causes ASP C# site to crash

My company has purchased the CoolUtils TotalPDFPrinterX from https://www.coolutils.com/TotalPDFPrinterX
I make an HTTP PUT from Postman to the API and I get “Could not get any response”.
When running on my Windows machine the PDF prints fine however on the server the site crashes and in the event log I get the error "A process serving application pool '[MY_APP_POOL]' failed to respond to a ping. The process id was '[MY_PROCESS_ID]'."
Here is my C# code:
PDFPrinterX ppx = new PDFPrinterX();
ppx.Print(fileName, printerName, "-ap Default");
if (ppx.ErrorMessage != null)
{
WriteToSQL(id, false, ppx.ErrorMessage, 2);
Console.WriteLine(ppx.ErrorMessage);
}
By writing to the event log I know the site crashes on this line: PDFPrinterX ppx = new PDFPrinterX(); I have also surrounded the above code with a try catch and no exception is thrown. The site still crashes.
Things I have tried:
Uninstalling and Reinstalling the CoolUtils software
Giving EVERYONE Full control to the site folder and the CoolUtils program folder
Creating a C# desktop application using the same code. THIS WORKS FINE ON THE SERVER. It's just the ASP site that crashes.
Does anyone know what might be causing this?
The more I research this thing online the more I'm inclined to say that ActiveX which is the X in PDFPrinterX doesn't seem to work well when hosted in IIS.
I've seen a few forums where they say it works fine when they debug on localhost but when deployed to server is crashes.
...works fine when used inside localhost(Visual studio)
One of their feature pages shows that it requires Win 2000/NT/XP/2003/Vista/7
You should look into whether your server supports ActiveX components that can work in conjunction with IIS.
Looking at one of their other products support page: TotalPDFConverterX:
the following note in my opinion may also apply to TotalPDFPrinterX, given its dependency on ActiveX as well.
Note: Pay attention to some details during installation Total PDF Converter X:
Do not forget to register ActiveX in your web-server account.
Total PDF Converter X supports only Internet Explorer, Mozilla and Firefox browsers.
ActiveX works only with 32-bit internet information server. 64-bit server is not supported. Use command line version instead.
Thanks to #Nkosi I was able to find a workaround.
ActiveX works only with 32-bit internet information server. 64-bit server is not supported. Use command line version instead.
Our IIS server is 64 bit so that is what probably caused the site to hang up.
Buttt... the command line still worked in printing the PDFs on the server.
Client side code (makes the HTTP POST):
private void SendToPrinter(string fileName, string printerName, int id, decimal documentSequence)
{
// use http client to make a POST to the print api
using (var client = new HttpClient())
{
// compile the values string to transfer in POST
// should finish to look something like this:
// C:\print.pdf&PRTFTW_OFIT&ValShip-155320-1
var values = new Dictionary<string, string>
{
{ "", fileName + "&" + printerName + "&ValShip-" + id + "-" + documentSequence},
};
// URL encode the values string
var content = new FormUrlEncodedContent(values);
// make the POST
// DEBUG
var response = client.PostAsync("http://localhost:54339/api/print", content);
// retrieve the response
var responseString = response.Result.ToString();
}
}
Server side code (receives the HTTP POST):
using System;
using System.Net.Http;
using System.Web;
using System.Web.Http;
namespace api.valbruna.print.Controllers
{
public class PrintController : ApiController
{
// POST api/print
public HttpResponseMessage Post(HttpRequestMessage request)
{
try
{
// parse the content recieved from the client
var content = request.Content.ReadAsStringAsync().Result;
// decode the content, certain characters such as
// '&' get encoded to URL lingo such as '%26'
content = HttpUtility.UrlDecode(content);
// split the string into 3 seperate parts
String[] str = content.Split('&');
// remove the equal sign from the first string
str[0] = str[0].Trim('=');
// compile the arguments command line string
// should finish to look something like this:
// "C:\Program Files (x86)\CoolUtils\Total PDF PrinterX\PDFPrinterX.exe" "C:\print.pdf" -p"\\PRINTERS\PRTFTW_OFIT" -ap Default -log "C:\inetpub\logs\CoolUtils\log-ValShip-155320-4.txt" -verbosity detail"
String arguments = "\"" + str[0] + "\" -p\"\\\\PRINTERS\\" + str[1] +
"\" -ap Default -log \"C:\\inetpub\\logs\\CoolUtils\\log-" + str[2] +
".txt\" -verbosity detail";
// file location for PDFPrinterX.exe
String file = #"C:\Program Files (x86)\CoolUtils\Total PDF PrinterX\PDFPrinterX.exe";
// start the process
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.FileName = file;
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
return new HttpResponseMessage() { Content = new StringContent(content) };
}
catch (Exception e)
{
return new HttpResponseMessage() { Content = new StringContent(e.Message) };
}
}
}
}

Download file from opensubtitles.org

I need to download files from opensubtitles.org trough my application which is written in GTK# and C#. The app is based on .NET 4.0 framework.
At first this was the code I was using:
var tZip = new FastZip();
try {
var tRequest = (HttpWebRequest)HttpWebRequest.Create(tDownloadUrl);
var tZipResponse = (HttpWebResponse)tRequest.GetResponse();
using (var tStream = tZipResponse.GetResponseStream()) {
using (var tMemStream = new MemoryStream()) {
tStream.CopyTo(tMemStream);
var tTempPath = Globals.video_location + "OSD";
Directory.CreateDirectory(tTempPath);
tZip.ExtractZip(tMemStream, tTempPath, FastZip.Overwrite.Always, null, #"\.srt$", null, false, true);
var tDirInfo = new DirectoryInfo(tTempPath);
var tFileInfo = new FileInfo(Globals.location_video);
var tSrtFile = tDirInfo.EnumerateFiles().FirstOrDefault();
if (tSrtFile == null) {
writeLog("No .srt file found in zip..");
goto text;
}
writeLog("Downloaded and unpacked: " + tSrtFile.Name);
File.Copy(tSrtFile.FullName, Globals.video_location+Globals.video_name+".srt", true);
Globals.savedTitle = Globals.video_location+Globals.video_name+".srt";
// clean up..
Directory.Delete(tTempPath, true);
writeLog("Deleted temp folder.");
return true;
}
}}
And that worked really well up until few days ago, now it is returning a bunch of html code instead of .zip file. I tried even something like this:
WebClient client = new WebClient();
client.DownloadFile(link, #"OSD\test.zip");
But everything just keeps returning bunch of html code.
The link I am usually trying to download is something like this:
http://dl.opensubtitles.org/en/download/subad/4287952
If you click on the link above it will just redirect you to the opensubtitles.org page of that particular subtitle. But if you right mouse click on that link and then select "open in new tab" or "open in new window" it will automatically start the download. (Tested in Firefox)
Also as soon as I paste that link in "Internet Download Manager" application, it will start the download of the zip file automatically.
If you can help me to resolve this problem I will truly be grateful.
Kind Regards.
I got into this problem because I was filtering the website xml directly. Like from a link such as this one: opensubtitles.org example
And in the beginning it used to work well, but then they changed something on the website and it stopped working. So what I did was build on top of this: OSHandler
That handler library is using XML-RPC so I believe there won't be any problems in the future.

How to launch a process which will open a text file in any editor and automatically move cursor to a certain line number?

From c#, I want to launch a process which will open a text file in any editor and automatically move cursor to a certain line number.
I can open a file using
Process.Start(#"c:\myfile.txt");
but I don't know how to move cursor at specific location in that file.
Answer with source code:
yes, I used notepad++
private void openLog() {
try {
// see if notepad++ is installed on user's machine
var nppDir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Notepad++", null, null);
if (nppDir != null) {
var nppExePath = Path.Combine(nppDir, "Notepad++.exe");
var nppReadmePath = Path.Combine(yourDirectory,fileName );
var line = 20;
var sb = new StringBuilder();
sb.AppendFormat("\"{0}\" -n{1}", nppReadmePath, lineNo);
Process.Start(nppExePath, sb.ToString());
} else {
string newPath = #"\\mySharedDrive\notpad++\bin\notepad++.exe";
Process.Start(newPath, #"\\" + filePath + " -n" + lineNo); // take exe from my shared drive
}
} catch (Exception e) {
Process.Start(#"\\" + FilePath); // open using notepad
}
}
Get Notepad++, then you can do this:
var nppDir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Notepad++", null, null);
var nppExePath = Path.Combine(nppDir, "Notepad++.exe");
var nppReadmePath = Path.Combine(nppDir, "readme.txt");
var line = 20;
var sb = new StringBuilder();
sb.AppendFormat("\"{0}\" -n{1}", nppReadmePath, line);
Process.Start(nppExePath, sb.ToString());
In this example we get install path of n++ from the registry, build path to exe and readme.txt file, opens its own readme.txt file with cursor on line 20.
Using StringBuilder is more efficient than using multiple appends (explanation somewhere on SO).
The solution very heavily depends on which process/editor is opened on your system. That editor would have to have a developer API that you could use to access functionality such as setting ranges and altering the cursor position. For example, if the editor that is opened is Microsoft Word, you would use the Word Interop API to set a selection at a specific position. There is no universal way to do this in 'any editor' since each one has its own API (or no outward facing API at all).
Perhaps you are going this the wrong way. I'm not sure what you are trying to accomplish, but I think it would be alot easier to just open the text file in an editor that belongs to your application. Perhaps another form with a WYSIWYG editor control. That way you have full control on where the cursor will land in that editor. Otherwise, there are just way too many unknowns for anything feasibly workable.

Categories

Resources