print pdf silently in c# - pdf-generation

I am trying to print pdf silently using adobe reader.
I have taken the example from the following location:
http://www.codeproject.com/Tips/598424/How-to-Silently-Print-PDFs-using-Adobe-Reader-and
I am able to work as desired with the above example code in my localhost.
But when I deploy my application on the server,I am unable to print the PDFs.
In my localhost on button click event,I am creating the PDFs and saving it to one location and printing the same.While printing adobe window opens and prints the PDFs and exits automatically.
The same doesn't work in my server.I am able to create and save PDFs,but adobe is not opening and printing my file.I am not even getting any exception/error.It simply doesn't show up adobe window.
Did anyone face the same issue.
Any help in this regard.
Thanks in advance.

EDIT:
If you are running on a Web Server using ASP.NET or in general IIS the new process executes on the Web server with restricted permissions. I point you out this answer that could explain the cause of your problem.
However the code you are using doesn't print any error message. You probably don't have access to the directory where the AcroRd32.exe is located.
Let's take this function from the article you posted:
public static Boolean PrintPDFs(string pdfFileName)
{
try
{
Process proc = new Process();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.Verb = "print";
//Define location of adobe reader/command line
//switches to launch adobe in "print" mode
proc.StartInfo.FileName =
#"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe";
proc.StartInfo.Arguments = String.Format(#"/p /h {0}", pdfFileName);
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (proc.HasExited == false)
{
proc.WaitForExit(10000);
}
proc.EnableRaisingEvents = true;
proc.Close();
KillAdobe("AcroRd32");
return true;
}
catch
{
return false;
}
}
PrintPDFs uses a process, which is called by the .NET framework using the Process class. In the StartInfo option you look carefully two options are set:
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
The first redirect the standard output stream to your application while the second hides the cmd window. The former is handy to use process without showing to the user a command window but the latter hide the console window. The main drawback is, if you're debugging, that you probably won't see error coming through.
One way to debug it would require to add the following to lines:
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
Console.WriteLine(proc.StandardOutput.ReadToEnd());
Another property you can look at is ExitCode. If that is greather than zero means that your process exit with some error.
hope it helps.

A silent printing can be achieved with an Acroread command line parameters or with a PDF JavaScript event handler (of course, if your PDF producer tool has a possibility to define/inject PDF's OpenAction handler).
See http://pd4ml.com/cookbook/pdf_automated_printing.htm
With the JavaScript approach you are not bound to a printer driver, network name or IP address. On the other hand, JavaScript in Acroread can be disabled, for example, by a corporate security policy.

use this with Ghostscript that is GNU:
ProcessStartInfo info = new ProcessStartInfo();
var FileName = #"C:\ResultadoFormulario_CClastMovements.pdf";
var pathPrinter = #"\\Server\namePrinter";
info.CreateNoWindow = true;
var pathGsw = #"path gswin64c here\";
info.WindowStyle = ProcessWindowStyle.Hidden;
string strCmdText = $"{pathGsw}gswin64c.exe -sDEVICE=mswinpr2 -dBATCH -dNOPAUSE -dNOPROMPT -dNoCancel -dPDFFitPage -sOutputFile=\"%printer%{direccionImpresora}\" \"{FileName}\"";
Process.Start("CMD.exe", strCmdText);

Related

Delete metadata descriptions with a Photoshop Script?

Is there an equivalent of deleteProperty(XMPConst.NS_DC, "description”) or some way to clear out EXIF:ImageDescription, XMP-dc:Description and IPTC:Caption-Abstract with a Photoshop Script (ie, JavaScript or AppleScript)?
I am trying to remove the tags/descriptions below from TIF, PSD and PSB images:
[EXIF:IFD0] ImageDescription
[XMP:XMP-dc] Description
[IPTC] Caption-Abstract
I can do this with Exiftool with this code:
exiftool -m -overwrite_original_in_place -EXIF:ImageDescription= -XMP-dc:Description= -IPTC:Caption-Abstract= FILE
While that works great for me, I have lots of vendors that would need this in their workflows so it would be easier for them to use an action with the Photoshop Events Manager "On Document Open", or via an Automator script (Java or AppleScript) in their workflows than installing ExifTool. Looking for some help to do this...
I don’t have much coding experience, but I found the JavaScript code below on PS-Scripts as a starting point. This code doesn't require Photoshop which I like and could be done with Automator, but it only references the one tag. Also, I don’t need to write anything to the tags as this code does (I’d prefer just to delete or wipe the content and/or tags so they don’t show up).
Code: Select allvar f = File("/c/captures/a.jpg");
setDescription(f,"My new description");
function setDescription( file, descStr ){
if ( !ExternalObject.AdobeXMPScript ) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
var xmpf = new XMPFile( File(file).fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE );
var xmp = xmpf.getXMP();
xmp.deleteProperty(XMPConst.NS_DC, "description");
xmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", descStr );
if (xmpf.canPutXMP( xmp )) {
xmpf.putXMP( xmp );
}
xmpf.closeFile( XMPConst.CLOSE_UPDATE_SAFELY );
}
And below is an attempt at the JavaScript that would be used as a Photoshop Event on "Open Document"; but again I don't know how to amend to ensure all 3 tags reference above are cleared:
function removeDescription() {
whatApp = String(app.name);
if(whatApp.search("Photoshop") > 0)
if(!documents.length) {
alert("There are no open documents. Please open a file to run this script.")
return;
}
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta( activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_DC, "description");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
}
removeDescription();
Finally, below was an alternate that was tried that wipes the Description, ImageDescription and Caption-Abstract on TIFFs and PNGs on the first try, but takes running through twice to work on a PSD/PSB/JPG. I think it has to do with the interaction between Description, ImageDescription and Caption-Abstract, and the solution possibly resides with amp.setLocalizedText to nothing?
function removeMetadata() {
whatApp = String(app.name);
if(whatApp.search("Photoshop") > 0) {
if(!documents.length) {
alert("There are no open documents. Please open a file to run this script.")
return;
}
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta( activeDocument.xmpMetadata.rawData);
if (xmp.doesArrayItemExist(XMPConst.NS_DC, "description", 1))
{
xmp.deleteArrayItem(XMPConst.NS_DC, "description", 1);
}
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
debugger
}
}
removeMetadata();
Here is an example Python script that uses the Pillow library to remove the metadata descriptions.
from PIL import Image
# Open the image file
image = Image.open('example.jpg')
# Remove the EXIF:ImageDescription metadata field
image.info.pop('EXIF:ImageDescription', None)
# Remove the XMP-dc:Description metadata field
image.info.pop('XMP-dc:Description', None)
# Remove the IPTC:Caption-Abstract metadata field
image.info.pop('IPTC:Caption-Abstract', None)
# Save the modified image file
image.save('example_modified.jpg')
Change "example.jpg" to your needs.
there may be other metadata fields that contain descriptions, depending on the specific image file format and how it was created. You may need to modify the script to remove additional fields if necessary.

SystemMediaTransportControls - setting properties not working

I'm trying to use the SystemMediaTransportControls in an background audio app. I am using the MediaPlayer class to play the audio. Setting the music properties, thumbnail all seems to work fine, but setting the control buttons (i.e. "next" button) is not working at all. My use case is somewhat unique in that I can't get a complete playlist at once, the next track is only available through a internal method call.
Here is what I am doing:
This part is working fine, the volume control shows all the audio information and thumbnail correctly:
var playbackItem = new MediaPlaybackItem(source);
var displayProperties = playbackItem.GetDisplayProperties();
displayProperties.Type = Windows.Media.MediaPlaybackType.Music;
displayProperties.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(_currentTrack.AlbumArtUrl));
displayProperties.MusicProperties.AlbumArtist = displayProperties.MusicProperties.Artist = _currentTrack.Artist;
displayProperties.MusicProperties.Title = _currentTrack.SongTitle;
displayProperties.MusicProperties.AlbumTitle = _currentTrack.Album;
playbackItem.CanSkip = true;
playbackItem.ApplyDisplayProperties(displayProperties);
_player.Source = playbackItem;
This part is not working, the "Next" button is still disabled, the "Record" button is not showing.
var smtc = _player.SystemMediaTransportControls;
smtc.ButtonPressed += OnSMTCButtonPressed;
smtc.IsEnabled = true;
smtc.IsNextEnabled = true;
smtc.IsRecordEnabled = true;
I've been trying to look for answers online but was unable to find anything useful. Any answer is appreciated.
In UWP, apart SMTC, there is something like CommandManager - to properly work with your SMTC you will have to disable it. Just put the line:
mediaPlayer.CommandManager.IsEnabled = false;
once you initialize the player and it should work. You will find more information at MSDN:
If you are using MediaPlayer to play media, you can get an instance of the SystemMediaTransportControls class by accessing the MediaPlayer.SystemMediaTransportControls property. If you are going to manually control the SMTC, you should disable the automatic integration provided by MediaPlayer by setting the CommandManager.IsEnabled property to false.

MATLAB to read in a password

I'm building a MATLAB application that authenticates a user's credentials.
I want to read in his password, and I want to hide his typed credentials somehow.
Some constraints:
I have to account for windows as well as linux/mac users.
I can't be assured of any programs (perl/python/VBS) in the user system.
Here's what I've tried:
Straight-up GUIDE
Works, but not an option as the user is likely to be running matlab in -nodesktop (or -nodisplay) mode.
MATLAB + Java
console.readPassword. This messes up my terminal horribly.
system() calls
Essentially I call bash or dos scripts based on OS.
I have the following call for linux/mac:
[status cred] = system('stty -echo; read cred; stty echo;echo ""; echo "$cred"');
This is supposed to pick up the user credentials and dump that on to 'cred'. I've checked that it works in the regular terminal, but executing it in MATLAB causes nothing to be output, and a Ctrl-C is required to bring back the >> prompt.
MATLAB Perl
The Windows MATLAB packages Perl, as pointed out in comments. I tried the following snippet:
use Term::ReadKey;
use Term::ReadLine;
ReadMode('noecho');
$yesnoline = Term::ReadLine->new("foo");
$pass = $yesnoline->readline();
printf "$pass";
ReadMode('restore');
And then called it as [result status] = perl('my_perl.pl'). Works great on Linux.
On Windows:
res =
GetConsoleMode failed, LastError=|6| at ReadKey.pm line 264.
sta =
9
My searches so far suggest that it's a problem related to the packaged version of perl for windows.
Any idea what's happening in the above approaches?
I suggest that you detect Windows installation (ispc), and handle them differently than Unix-like systems, by creating a MATLAB GUI or something similar..
Here is one possible solution for Windows using .NET Windows Forms from inside MATLAB:
function pass = getPasswordNET()
%# password return value
pass = '';
%# hidden figure used to wait for button press
fig = figure('Visible','off', ...
'IntegerHandle','off', 'HandleVisibility','off');
%# create and show the Windows Forms GUI
[handles,lh] = InitializeComponents();
handles.frm.Show();
%# block execution until figure is closed
waitfor(fig)
%# remove the listeners
delete(lh);
return;
%# create GUI
function [handles,lh] = InitializeComponents()
%# import assembly
NET.addAssembly('System.Windows.Forms');
%# form
frm = System.Windows.Forms.Form();
frm.SuspendLayout();
%# textbox
tb = System.Windows.Forms.TextBox();
tb.Dock = System.Windows.Forms.DockStyle.Fill;
tb.Text = '';
tb.PasswordChar = '*';
tb.MaxLength = 14;
%# button
bt = System.Windows.Forms.Button();
bt.Dock = System.Windows.Forms.DockStyle.Bottom;
bt.Text = 'Submit';
%# setup the form
frm.Text = 'Password';
frm.ClientSize = System.Drawing.Size(250, 40);
frm.Controls.Add(tb);
frm.Controls.Add(bt);
frm.ResumeLayout(false);
frm.PerformLayout();
%# add event listeners
lh(1) = addlistener(bt, 'Click', #onClick);
lh(2) = addlistener(frm, 'FormClosing', #onClose);
%# return handles structure
handles = struct('frm',frm, 'tb',tb, 'bt',bt);
end
%# event handlers
function onClick(~,~)
%# get password from textbox
pass = char(handles.tb.Text);
%# close form
handles.frm.Close();
end
function onClose(~,~)
%# delete hidden figure (to unblock and return from function)
close(fig)
end
end
I tested the above on my machine, and it worked even when MATLAB was started in headless mode:
matlab.exe -nodesktop -noFigureWindows
then called it as:
>> pass = getPasswordNET()
pass =
secret_password
It should be straightforward to do something similar in Java using Swing's JPasswordField
Java getPassword
I haven't yet managed to get the getPassword approach to return the console to the normal state - I'm assuming your code looks something like:
import java.lang.*
cs = System.console()
a = cs.readPassword()
Could you confirm this?
Python solution
If the solution has to be multi-platform, and you don't mind Python being a dependency, I would suggest writing a very simple python script and using this with a Matlab system call, something like
file: usergetpass.py
import getpass
import os
os.sys.stdout.write(getpass.getpass())
then in matlab
[status,pass] = system('python usergetpass.py');
You would then have to (trivially) parse pass though, the actual password is contained on line 3 of pass.
So you could put the above into your own mini matlab function,
function out = getpass()
[status, pass] = system('python usergetpass.py');
out = pass(13:end-1);
Note: I can use this because the password always occurs at that point in the pass variable.

WIA + network scanner with adf = 1 page

I am writing a program to work with a network scanner through WIA.
Everything works fine when scanning only one page. When I turn on the feeder:
foreach (WIA.Property deviceProperty in wia.Properties)
{
if (deviceProperty.Name == "Document Handling Select")
{
int value = duplex ? 0x004 : 0x001;
deviceProperty.set_Value(value);
}
}
the program receives a scan, the signal that there are still documents in the feeder and falls off with com error (scanner continues to scan).
Here's the code check the pages in the feeder:
//determine if there are any more pages waiting
Property documentHandlingSelect = null;
Property documentHandlingStatus = null;
foreach (Property prop in wia.Properties)
{
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}
if ((Convert.ToUInt32(documentHandlingSelect.get_Value()) & 0x00000001) != 0)
{
return ((Convert.ToUInt32(documentHandlingStatus.get_Value()) & 0x00000001) != 0);
}
return false;
Getting the picture code:
imgFile = (ImageFile)WiaCommonDialog.ShowTransfer(item, wiaFormatJPEG, false);
Unfortunately could not find an example of using WIA WSD. Perhaps there are some settings to get multiple images through WSD.
I had almost the same problem using WIA 2.0 with vba to control a Brother MFC-5895CW Multi-Function Scanner.
When I transferred scans from the ADF I was not capable to catch more than 2 pictures to image-objects (and I tried probably every existing option and worked days and hours on that problem!)
The only solution I found with that scanner was to use the ShowAcquisitionWizard-method of the WIA.CommonDialog-Object to batch-transfer all scanned files to a specified folder. It was more a workaround than a satisfying solution for me because the postprocessing would have become more complicated.
Surprise surprise, I tried the same procedure on the neat-scanner of my client... ShowAcquisitionWizard delivered only one scanned page to the specified folder, the other pages disappeared.
To my second surprise with the 'CommonDialog.ShowTransfer'-method I was able to transfer all scanned documents picture by picture into image-objects in my application.

mouse double click is not working quite good

I am using the following code to record screen, when recording, when using mouse to double click some item, for example double click a ppt to open it in PowerPoint, it is not very responsive. I have tried and it is much better when using screen recording function of Windows Media Encoder 9. Any ideas what is wrong?
My environment: Windows Vista + Windows Media Encoder 9 + VSTS 2008 + C#. I wrote the following code in the initialization code of a Windows Forms application, and I suspect something wrong with my Windows Forms application?
My code,
IWMEncSourceGroup SrcGrp;
IWMEncSourceGroupCollection SrcGrpColl;
SrcGrpColl = encoder.SourceGroupCollection;
SrcGrp = (IWMEncSourceGroup)SrcGrpColl.Add("SG_1");
IWMEncVideoSource2 SrcVid;
IWMEncSource SrcAud;
SrcVid = (IWMEncVideoSource2)SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);
SrcAud = SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
SrcVid.SetInput("ScreenCap://ScreenCapture1", "", "");
SrcAud.SetInput("Device://Default_Audio_Device", "", "");
// Specify a file object in which to save encoded content.
IWMEncFile File = encoder.File;
string CurrentFileName = Guid.NewGuid().ToString();
File.LocalFileName = CurrentFileName;
CurrentFileName = File.LocalFileName;
// Choose a profile from the collection.
IWMEncProfileCollection ProColl = encoder.ProfileCollection;
IWMEncProfile Pro;
for (int i = 0; i < ProColl.Count; i++)
{
Pro = ProColl.Item(i);
if (Pro.Name == "Screen Video/Audio High (CBR)")
{
SrcGrp.set_Profile(Pro);
break;
}
}
encoder.Start();
thanks in advance,
George
I faced the same problem. But the problem doesn't reside in your code or mine. When I tried to capture screen from Windows Media Encoder application itself I faced the same problem too in about 50% of the sessions. It's evident that it's a bug in WindowsMediaEncoder itself.
George
Here are a couple options (from http://www.windowsmoviemakers.net/Forums/ShowPost.aspx?PostID=1982):
Enable the MouseKeys Accessibility option, and type + to double-click
Run the encoder and target application on different machines, and capture a remote desktop session

Resources