I'm using the COM objects from Office 2007 to handle and print ms-office files. I don't have any problems with word and excel documents, but i just can't print Power Point docs.
the code bellow just opens the file send a job to the printer but nothing gets printed
what am i doing wrong? =(
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Main
{
class PrintPPoint
{
public static void PrintPPointDocument(string filename, int copies, string range)
{
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;
//app.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
work = presprint.Open(filename, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoFalse);
work.PrintOptions.PrintInBackground = 0;
work.PrintOptions.ActivePrinter = app.ActivePrinter;
if (range.Equals("0"))
{
work.PrintOut(0, 1, app.ActivePrinter, copies, Microsoft.Office.Core.MsoTriState.msoFalse);
}
else
{
string[] toprintsheet = range.Split(new char[] { ',' });
foreach (string aux in toprintsheet)
{
work.PrintOptions.PrintInBackground = 0;
work.PrintOptions.ActivePrinter = app.ActivePrinter;
if (aux.Contains("-"))
{
int from = 0, to = 0;
string[] SplitRange = aux.Split(new char[] { '-' });
from = Convert.ToInt16(SplitRange[0]);
to = Convert.ToInt16(SplitRange[1]);
work.PrintOut(from, to, app.ActivePrinter, 1, Microsoft.Office.Core.MsoTriState.msoFalse);
}
else
{
work.PrintOut(Convert.ToInt16(aux), Convert.ToInt16(aux), app.ActivePrinter, copies, Microsoft.Office.Core.MsoTriState.msoFalse);
}
}
}
work.Close();
app.Quit();
}
}
}
I just needed to set
PrintOptions.PrintInBackground = Microsoft.Office.Core.MsoTriState.msoFalse
That lets the jobs complete.
I can't tell you but I bet you can easily find out yourself...
I assume that this is an application that interacts with the desktop and not some background service.
I would step through the code slowly and see if it works.. (for both app.visible = true and not.) If it works, it may be a race between ppoint printing functionality and ppoint closing the document/quiting. (Even though you've turned off background printing) and you have check for that...
Good luck
Related
Below is the code I am using, I expect that each line will be wrote to the file during each iteration of the loop. What I am finding is that if I end the program early using ctrl-c or just closing the window the file is empty.
I need to write to the file quite often, I have 33k items to add to the file and its almost inevitable something goes wrong before the 33k items are added to the CsvWriter. If I short circuit the loop to say 20 items and let it finish, the output file is correct. How do I solve this issue?
int i = 0;
IList<string> pcodes = FindAutobidPcodes();
using (StreamWriter sw = new StreamWriter($"HPH_Catalog_{DateTime.Now.Ticks}.csv"))
using (CsvWriter cw = new CsvWriter(sw, CultureInfo.InvariantCulture))
{
cw.Configuration.RegisterClassMap<ProductMap>();
foreach (string code in pcodes)
{
string search = $"&search=%7b\"catalog\"%3a\"{catalog}\"%2c\"text\"%3a%7b\"{code}\"%3a\"{code}\"%7d%7d";
searchQuery.Query = $"{RandomString()}{limit}{page}{search}{gtemplate}&token={token}";
WebPage webPage = QueryProductData(searchQuery.ToString());
cw.WriteRecord(Product.ParseJSON(webPage));
cw.NextRecord();
i++;
if(i == 20) { return; }
}
}
What you can do is flushing the StreamWriter after each iteration eg:
static void Main(string[] args)
{
using (StreamWriter sw = new StreamWriter($"HPH_Catalog_{DateTime.Now.Ticks}.csv"))
using (CsvWriter cw = new CsvWriter(sw, CultureInfo.InvariantCulture))
{
for (int i = 0; i < 34000; i++)
{
cw.WriteField(i);
cw.NextRecord();
sw.Flush();
System.Threading.Thread.Sleep(100);
}
}
}
You can also encapsulate the inner foor-each loop into a try statement- if something goes wrong whilst looping then in the catch statement flush and dispose.
I'm stuck here while opening and reading csv file in c# program. Ive just started working upon ILNumerics to display 3D matrix graph, but the Exception rises with
"Could not find file 'C:\Users\asd\Documents\Visual Studio 2013\Projects\matrixgraph\martix\bin\Debug\stats.csv'."
Please help me out!
Below is the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using ILNumerics;
using ILNumerics.Drawing;
using ILNumerics.Drawing.Plotting;
namespace martix
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ilPanel1_Load(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
string path = #"C:\Users\asd\Documents\Visual Studio 2013\Projects\matrixgraph\martix\bin\Debug\stats.csv";
StreamReader sr = new StreamReader(File.Open(path, FileMode.Open));
string dataLines = string.Empty;
while (sr.Peek() != -1)
dataLines += sr.ReadLine().Replace(";", ",") + "\n";
sr.Close();
dataLines = dataLines.Trim('\n');
//Convert the data-string into an ILArray
ILArray<int> AN = ILMath.csvread<int>(dataLines);
//Create a new scene, which is the base for our graph
var scene = new ILScene();
using (ILScope.Enter())
{
//Convert all data points to float
ILArray<float> A = ILMath.tosingle(AN);
//Add a plot to the scene and configure it
scene.Add(new ILPlotCube
{
//Render in 3D
TwoDMode = false,
//Add 3 axes
Axes =
{
XAxis =
{
Label = { Text = "Price in $" },
GridMajor =
{
DashStyle = DashStyle.Dashed,
Color = Color.DarkGray,
Width = 1
}
},
YAxis =
{
Label = { Text = "Rating count" },
GridMajor =
{
DashStyle = DashStyle.Dashed,
Color = Color.DarkGray,
Width = 1
}
},
ZAxis =
{
Label = { Text = "Download count" }
}
},
//Add the data points
Children = {
new ILPoints {
Positions = A
},
},
//Set start rotation for 3D rendered graph
Rotation = Matrix4.Rotation(new Vector3(1, 1, 1), 0.5f)
});
}
//Add the scene to the ILPanel
ilPanel1.Scene = scene;
}
}
}
It may be the spaces you have in the path. Nevermind, you're using verbatim string.
Are you sure that path is accessible and is not a networked mapped path? Can you move your file temporarily? It really seems that you don't have access to that path.
Also you should try doing the following to pinpoint the issue:
System.IO.FileInfo fi = null;
try
{
fi = new System.IO.FileInfo(path);
}
catch (ArgumentException) {... }
catch (System.IO.PathTooLongException) {... }
catch (NotSupportedException) {... }
if (ReferenceEquals(fi, null))
{
...
// file name is not valid
}
else
{
...
// file name is valid... May check for existence by calling fi.Exists.
}
EDIT:
use System.IO.Directory.GetFiles to list the exact names of the files in that folder, it may be that the file name is different (stats.csv.csv) and window explorer is hiding the extension.
Got the solution while trying. I created the csv file programatically and this time it read the file.
Just added the few line before the path and modified the path.
StringBuilder csv = new StringBuilder();
csv.AppendLine("112,113,222");
string csvpath = #"C:\\stats\xyz.csv";
File.AppendAllText(csvpath,csv.ToString());
string path = #"C:\stats\xyz.csv";
And thats it. Anyways Thanks for helping :)
The following code returns only three serial ports (com3, com4 and com5). The firmware that I would like to access is located on a USB plug multiplier. How can I access the serial ports of this mulitplier and how can I identify the specific USB containing the firmware that I want to send information to?
using System;
using System.IO.Ports;
namespace SerialPortExample
{
class SerialPortExample
{
public static void Main()
{
string[] ports = SerialPort.GetPortNames();
Console.WriteLine("The following serial ports were found:");
foreach (string port in ports)
{
Console.WriteLine(port);
}
Console.ReadLine();
}
}
}
Many thanks in advance!
This is a pretty big usability problem and caused by USB drivers taking a shortcut and emulating a serial port to make it easy to interface with them. Serial ports are very primitive devices, which makes their api very easy to use. But lacks any kind of support for plug-and-play, there's no way to get a decent notification for them. The driver just picks an arbitrary port number and it is up to the user to figure out which one it might be. Trial and error stuff. This didn't use to be a problem, serial ports had a connector mounted on the machine's back panel that was clearly labeled with the COM port name.
You can possibly get some mileage out of WMI, it lets you enumerate serial port devices with the Win32_SerialPort query. What you get is fairly unpredictable, it completely depends on the driver to supply the data. Best way to experiment with that is with the WMI Code Creator utility, it can also auto-generate the C# code you need. Unfortunately I can't find the download location anymore, this appears to have been removed in the past couple of weeks. Hope you can find an alternative.
The code below does a good job finding the specific ports:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Windows.Forms;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
MyClass x = new MyClass();
var com = x.GetCOMs();
foreach (string port in com)
{
Console.WriteLine(port);
}
Console.ReadLine();
}
}
class MyClass
{
public List<string> GetCOMs()
{
List<string> coms = new List<string>();
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0");
foreach (ManagementObject obj in searcher.Get())
{
object captionObj = obj["Caption"];
if (captionObj != null)
{
string caption = captionObj.ToString();
if (caption.Contains("(COM"))
{
coms.Add(caption);
}
}
}
m_ParseCOMs(ref coms);
}
catch (ManagementException ex)
{
MessageBox.Show("An error occurred while querying for WMI data: " + ex.Message);
return coms;
}
return coms;
}
private void m_ParseCOMs(ref List<string> comPorts)
{
string[] temp;
List<string> temp2 = new List<string>();
int index = 0;
foreach (string s in comPorts)
{
string temp3 = "";
temp = s.Split(' ');
temp3 += temp[temp.Length - 1] + " - ";
for (int i = 0; i < temp.Length - 1; i++)
{
temp3 += temp[i] + " ";
}
temp2.Insert(index, temp3);
index++;
}
comPorts = temp2;
}
}
}
I am using the HtmlTextWriter to create some HTML for me. I want to test if my page actually works but it doesnt render the div.
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class web_content_notes_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
/* Configuration Start */
string thumb_directory = "img/thumbs";
string orig_directory = "img/original";
int stage_width = 600;
int stage_height = 480;
Random random = new Random();
// array of allowed file type extensions
string[] allowed_types = { "bmp", "gif", "png", "jpg", "jpeg", "doc", "xls" };
/* Opening the thumbnail directory and looping through all the thumbs: */
foreach (string file in Directory.GetFiles(thumb_directory))
{
string title = Path.GetFileNameWithoutExtension(file);
if (allowed_types.Equals(Path.GetExtension(file)) == true)
{
int left = random.Next(0, stage_width);
int top = random.Next(0, 400);
int rotation = random.Next(-40, -40);
if ((top > stage_height - 130) && (left > stage_width - 230))
{
top -= 120 + 130;
left -= 230;
}
}
//display the files in the directory in a label for testing
Label1.Text = (file);
StringWriter stringWriter = new StringWriter();
// Put HtmlTextWriter in using block because it needs to call Dispose.
using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
// The important part:
writer.Write("<div>testing123</div>");
}
}
}
I want to add the various variables into the div.
How do i do this? I remember in classic asp/vbscript you had to wrap the code in <% code %> not sure if this is the case in ASP.NET / C#
I want to test if my page actually works but it doesnt render the div.
Well no, it wouldn't. Look at what you're doing:
StringWriter stringWriter = new StringWriter();
using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
writer.Write("<div>testing123</div>");
So, you're writing to a StringWriter. You're then doing nothing with that string writer: the text is in memory, and you're letting it get garbage collected, basically.
If you want to write to the Page's response, you'd have to write the result to Page.Response. But you should decide whether you want control the whole of the response for the request - in which case Page probably isn't terribly appropriate - or just a single control, in which case you should probably be putting your code in a custom control.
I'm new with C#. I've written code to open a CSV file from my documents on my local machine. It works well and the data parsing works. Trouble is when I change the code to open the file from an internet site I cannot get it to work. I am able to open this file using VBA but I now want to use C# ADO.NET. I cannot find the answer by searching with Google. Can anyone help with the code and/or point me to a website with a good tutorial. All help much appreciated. Code attached, I'm sure the problem is with lines 24 - 26;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//
// Read in a file line-by-line, and store it all in a List.
//
int i = 0;
DateTime dte;
List<string> list = new List<string>();
float[] Prices = new float[4];
WebClient wc = new WebClient();
byte[] data = wc.DownloadData("http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
using (StreamReader reader = new StreamReader(wc))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//list.Add(line); // Add to list.
Console.WriteLine(line); // Write to console.
string[] parts = line.Split(',');
int DateSetter = 1;
int DateDone = 0;
int CountFloat = 0;
int PricesDone = 0;
Double Volume = 0;
foreach (string part in parts)
{
Console.WriteLine("{0} : {1}", i, part);
if (DateSetter == 1)
{
dte = DateTime.Parse(part);
DateSetter = 2;
Console.WriteLine(dte);
}
if (DateDone == 1)
{
if (DateSetter < 6)
{
Prices[CountFloat] = float.Parse(part);
CountFloat++;
DateSetter++;
Console.WriteLine(Prices[3]);
}
}
DateDone = 1;
if (PricesDone == 1)
{
Volume = double.Parse(part);
Console.WriteLine(Volume);
}
if (DateSetter == 6)
{
PricesDone = 1;
}
}
}
}
Console.ReadLine();
}
}
}
Your code as pasted would not compile. You can however use the WebClient to download to a string, then split the string into lines:
string content;
using(WebClient wc = new WebClient())
content = wc.DownloadString("http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
foreach(var line in content.Split(new string [] {Environment.NewLine}, StringSplitOptions.None))
{
//...
}
Another option is to download data as you're doing, and then wrap it with a MemoryStream:
WebClient wc = new WebClient();
byte[] data = wc.DownloadData(
"http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
using (var ms = new MemoryStream(data))
{
using (var reader = new StreamReader(ms))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// do whatever
}
}
}
The advantage of this over splitting the string is that it uses considerably less memory.