I am trying to print PowerPoint docs through my windows application in C#. I am using Microsoft.Office.Interop.PowerPoint for this functionality. Following is the code which I have used. It sends the request to printer but nothing gets printed.
string filename = "C:\\test.ppt";
int copies = 1;
Microsoft.Office.Interop.PowerPoint.Presentation work = null;
Microsoft.Office.Interop.PowerPoint.Application app = new Microsoft.Office.Interop.PowerPoint.ApplicationClass();
Microsoft.Office.Interop.PowerPoint.Presentations presprint = app.Presentations;
work = presprint.Open(filename, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoFalse);
//app.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
work.PrintOptions.PrintInBackground = Microsoft.Office.Core.MsoTriState.msoFalse;
//work.PrintOptions.PrintInBackground = Microsoft.Office.Core.MsoTriState.msoTrue;
//work.PrintOptions.ActivePrinter = "HP LaserJet 5000 Series PCL6";
work.PrintOptions.ActivePrinter = app.ActivePrinter;
work.PrintOut(1, work.Slides.Count, app.ActivePrinter, copies, Microsoft.Office.Core.MsoTriState.msoFalse);
work.Close();
app.Quit();`
When debugging, try halting after work.PrintOut and check your printer to see if the jobs arrives. I'm guessing you are closing PowerPoint too fast.
Related
I am creating pdf files in an asp.net project that is being stored on the server in a folder. When a user wants to print this file, I need the user to specify which printer among all the label printers on the network since it may contain numeral laser printers as well. I have tried creating a print process but this send the pdf file straight to the default printer. is there any way to display the print dialog so that users can select the required printer?
printjob.StartInfo.FileName = pdfFileName;<br/>
printjob.StartInfo.Verb = "Print";<br/>
printjob.StartInfo.CreateNoWindow = false;<br/>
printjob.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
PrinterSettings setting = new PrinterSettings();<br/>
printjob.Start();
This can be achieved by Spire.pdf.dll reference.
To install this Open package manager console and type Install-Package Spire.pdf. this will install spire.pdf. Now the following code will help you print the pdf files.
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("D:\\sample.pdf");
//Use the default printer to print all the pages
//doc.PrintDocument.Print();
//Set the printer and select the pages you want to print
PrintDialog dialogPrint = new PrintDialog();
dialogPrint.AllowPrintToFile = true;
dialogPrint.AllowSomePages = true;
dialogPrint.PrinterSettings.MinimumPage = 1;
dialogPrint.PrinterSettings.MaximumPage = doc.Pages.Count;
dialogPrint.PrinterSettings.FromPage = 1;
dialogPrint.PrinterSettings.ToPage = doc.Pages.Count;
if (dialogPrint.ShowDialog() == DialogResult.OK)
{
doc.PrintFromPage = dialogPrint.PrinterSettings.FromPage;
doc.PrintToPage = dialogPrint.PrinterSettings.ToPage;
doc.PrinterName = dialogPrint.PrinterSettings.PrinterName;
PrintDocument printDoc = doc.PrintDocument;
dialogPrint.Document = printDoc;
printDoc.Print();
}
I've an RDP file that successfully start a RemoteApp.
remoteapplicationmode:i:1
remoteapplicationprogram:s:||application
remoteapplicationname:s:application.exe
remoteapplicationcmdline:s:
authentication level:i:2
gatewayusagemethod:i:2
gatewayprofileusagemethod:i:1
gatewaycredentialssource:i:0
full address:s:aaa.bbb.ccc.com
I tried to copy its settings into my C# objects:
AxMsRdpClient7NotSafeForScripting rc = new AxMsRdpClient7NotSafeForScripting();
rc.OnConnected += (_1, _2) => { rc.RemoteProgram2.ServerStartProgram("application.exe", "", "%HOMEDRIVE%" + "%HOMEPATH%", true, "", true); };
rc.RemoteProgram2.RemoteProgramMode = true;
rc.RemoteProgram2.RemoteApplicationProgram = "||application";
rc.RemoteProgram2.RemoteApplicationName = "application.exe";
rc.TransportSettings.GatewayUsageMethod = 1;
rc.TransportSettings.GatewayProfileUsageMethod = 1;
rc.TransportSettings.GatewayCredsSource = 0;
rc.Server = "aaa.bbb.ccc.com";
rc.UserName = "DOMAIN\\user";
rc.AdvancedSettings7.PublicMode = false;
rc.AdvancedSettings7.ClearTextPassword = "pass";
rc.AdvancedSettings7.AuthenticationLevel = 2;
rc.DesktopWidth = SystemInformation.VirtualScreen.Width;
rc.DesktopHeight = SystemInformation.VirtualScreen.Height;
rc.AdvancedSettings7.SmartSizing = true;
rc.Connect();
I've been searching everywhere but I wasn't able to find any example of how to launch a RemoteApp programmatically.
I've red this page, but it was not very helpfull. The client (a COM control) is connecting successfully, but it just displays a blue screen and no RemoteApp is launched.
Furthermore, I'm not sure that the right method to launch rc.RemoteProgram2.ServerStartProgram, because it takes paths as arguments, while in my RDP file no path is present!
Can anyone help me? I'm using the right objects to do what I want?
The server runs Windows Server 2008R2
If all you want to do is pragmatically launch a RemoteApp you already have an rdp file for, then just start it as a process:
System.Diagnostics.Process.Start(#"C:\Path_To_Rdp_File.rdp");
I am printing a 3 inch receipt using a LocalReport with code from "Walkthrough: Printing a Local Report without Preview"
Some printers require the DeviceInfo PageWidth to be 8.5in to work correctly and some require 3.0in. Its appears that the report is being stretched to fill a wrong sized page. I have tried to adjust both the Report Paper Size and the Printer Paper size but can't seem to get the right combination.
Has anybody experienced this?
I figured this out. You need to account for the printer dpi.
Get the Printer Default Page Settings:
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = printerName;
this.defaultPageSettings = ps.DefaultPageSettings;
The Build the DeviceInfo Xml with that info:
private string BuildDeviceInfo()
{
StringBuilder returnValue;
System.Xml.XmlWriter writer;
returnValue = new StringBuilder(1024);
writer = System.Xml.XmlWriter.Create(returnValue);
writer.WriteStartElement("DeviceInfo");
writer.WriteElementString("OutputFormat", "EMF");
if (defaultPageSettings != null)
{
// DPI will keep the output from scaling in weird ways
writer.WriteElementString("PrintDpiX", defaultPageSettings.PrinterResolution.X.ToString());
writer.WriteElementString("PrintDpiY", defaultPageSettings.PrinterResolution.Y.ToString());
writer.WriteElementString("PageWidth", (defaultPageSettings.PaperSize.Width / 100m).ToString("F2") + "in");
writer.WriteElementString("PageHeight", (defaultPageSettings.PaperSize.Height / 100m).ToString("F2") + "in");
}
writer.Close();
return returnValue.ToString();
}
This worked for me. I'm printing from a WPF app to a STAR TSP100 receipt printer. When I set the margins & page size myself it came out huge, but when I calculated the minimum margins and page size as well as set the dpi from default printer settings the receipts printed correctly.
I used this to figure out the minimum margins: (H/T http://www.dreamincode.net/forums/topic/135864-printing-with-minimum-margins-specified-by-the-printer/)
Dim minimumMarginLeft, minimumMarginRight, minimumMarginTop,
minimumMarginBottom As Single
minimumMarginLeft = PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Left
minimumMarginRight = PrintDialog1.PrinterSettings.DefaultPageSettings.PaperSize.Width - _
PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Right
minimumMarginTop = PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Top
minimumMarginBottom = PrintDialog1.PrinterSettings.DefaultPageSettings.PaperSize.Height - _
PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Bottom
-I figured this out. You need to account for the printer dpi.
-Get the Printer Default Page Settings:
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = printerName;
this.defaultPageSettings = ps.DefaultPageSettings; The Build the DeviceInfo Xml with that info:
private string BuildDeviceInfo()
{
StringBuilder returnValue;
System.Xml.XmlWriter writer;
returnValue = new StringBuilder(1024);
writer = System.Xml.XmlWriter.Create(returnValue);
writer.WriteStartElement("DeviceInfo");
writer.WriteElementString("OutputFormat", "EMF");
if (defaultPageSettings != null)
{
// DPI will keep the output from scaling in weird ways
writer.WriteElementString("PrintDpiX", defaultPageSettings.PrinterResolution.X.ToString());
writer.WriteElementString("PrintDpiY", defaultPageSettings.PrinterResolution.Y.ToString());
writer.WriteElementString("PageWidth", (defaultPageSettings.PaperSize.Width / 100m).ToString("F2") + "in");
writer.WriteElementString("PageHeight", (defaultPageSettings.PaperSize.Height / 100m).ToString("F2") + "in");
}
writer.Close();
return returnValue.ToString();
}
Below are my code:
PosExplorer posExplorer = new PosExplorer();
DeviceCollection receiptPrinterDevices = posExplorer.GetDevices(DeviceType.PosPrinter);
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter,"SRP2");
PosPrinter printer = (PosPrinter)posExplorer.CreateInstance(receiptPrinterDevice);
printer.Open();
printer.Claim(10000);
printer.DeviceEnabled = true;
printer.PrintNormal(PrinterStation.Receipt, "test print 1");
I debug and everything went through without exception, already confirmed also that the printer targeted is the correct one, however the printer is not printing anything. Is there any step that I did wrong? Any guidance is greatly appreciated. Thanks
If it helps, My Printer Interface via Ethernet to a specific IP.
The problem appears to be that you are not sending a new line character (\n) at the end of your PrintNormal string, without it the service object will just buffer the line data, waiting until it sees the \n before sending the data to the device.
printer.PrintNormal(PrinterStation.Receipt, "test print 1\n");
From the POS for .net Documentation on PrintNormal
Newline / Line Feed (10 Decimal)
Print any data in the line buffer, and feed to the next print line. (A carriage return is not required in order to print the line.)
This is because the printer must print one complete line at a time, so it waits until you tell it that you have completed a line before starting to print, this allows you to use 2 or more PrintNormal calls for a single line of printout to build up the line data if needed (e.g. in a loop).
I have ran the below code on a networked POS Printer (Tysso PRP-250) and with the \n it prints the line, without it it does not.
PosExplorer posExplorer = new PosExplorer();
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter, "SRP2");
PosPrinter printer = posExplorer.CreateInstance(receiptPrinterDevice) as PosPrinter;
printer.Open();
printer.Claim(10000);
if (printer.Claimed)
{
printer.DeviceEnabled = true;
printer.PrintNormal(PrinterStation.Receipt, "test print 1\n");
printer.DeviceEnabled = false;
}
printer.Release();
printer.Close();
I am looking for a code snippet that does just this, preferably in C# or even Perl.
I hope this not a big task ;)
The following will open C:\presentation1.ppt and save the slides as C:\Presentation1\slide1.jpg etc.
If you need to get the interop assembly, it is available under 'Tools' in the Office install program, or you can download it from here (office 2003). You should be able to find the links for other versions from there if you have a newer version of office.
using Microsoft.Office.Core;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
namespace PPInterop
{
class Program
{
static void Main(string[] args)
{
var app = new PowerPoint.Application();
var pres = app.Presentations;
var file = pres.Open(#"C:\Presentation1.ppt", MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);
file.SaveCopyAs(#"C:\presentation1.jpg", Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsJPG, MsoTriState.msoTrue);
}
}
}
Edit:
Sinan's version using export looks to be a bit better option since you can specify an output resolution. For C#, change the last line above to:
file.Export(#"C:\presentation1.jpg", "JPG", 1024, 768);
As Kev points out, don't use this on a web server. However, the following Perl script is perfectly fine for offline file conversion etc:
#!/usr/bin/perl
use strict;
use warnings;
use Win32::OLE;
use Win32::OLE::Const 'Microsoft PowerPoint';
$Win32::OLE::Warn = 3;
use File::Basename;
use File::Spec::Functions qw( catfile );
my $EXPORT_DIR = catfile $ENV{TEMP}, 'ppt';
my ($ppt) = #ARGV;
defined $ppt or do {
my $progname = fileparse $0;
warn "Usage: $progname output_filename\n";
exit 1;
};
my $app = get_powerpoint();
$app->{Visible} = 1;
my $presentation = $app->Presentations->Open($ppt);
die "Could not open '$ppt'\n" unless $presentation;
$presentation->Export(
catfile( $EXPORT_DIR, basename $ppt ),
'JPG',
1024,
768,
);
sub get_powerpoint {
my $app;
eval { $app = Win32::OLE->GetActiveObject('PowerPoint.Application') };
die "$#\n" if $#;
unless(defined $app) {
$app = Win32::OLE->new('PowerPoint.Application',
sub { $_[0]->Quit }
) or die sprintf(
"Cannot start PowerPoint: '%s'\n", Win32::OLE->LastError
);
}
return $app;
}