I have recently started using C# over the past year so I'm somewhat new to this, but can usually hack through things with some effort, but this one is eluding me. We use TestTrack for development bug/issue tracking at our company. I've created a custom windows forms app to be the front-end to TestTrack for one of our departments. It connects using SOAP. I'm not using WPF/WCF and don't want to go that route. I'm having difficulty finding any examples of how to correctly encode a file for attachment that is a PDF. The code below does actually create an attachment in TestTrack to an already-existing issue, but when you try to open it in TestTrack, it pops up an error message that says "Insufficient Data For An Image". The example below does work if you're wanting to add a text file to TestTrack using SOAP. I'm wanting to know what I need to change below so that I can get a PDF file into TestTrack and then be able to open it in the TestTrack application without the error mentioned above. Thanks in advance for any input/help.
public void getAttachments(long lSession, CDefect def)
{
ttsoapcgi cgiengine = new ttsoapcgi();
// Lock the defect for edit.
CDefect lockedDefect = cgiengine.editDefect(lSession, def.recordid, "", false);
string attachment = "c:\\TEST\\TEST_PDF.PDF";
CFileAttachment file = new CFileAttachment();
file.mstrFileName = Path.GetFileName(attachment);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
StreamReader reader = new StreamReader(attachment);
file.mstrFileName = Path.GetFileName(attachment);
file.mpFileData = enc.GetBytes(reader.ReadToEnd());
reader.Close();
CReportedByRecord reprec = lockedDefect.reportedbylist[0];
CFileAttachment[] afile = reprec.attachmentlist;
if (afile == null)
{
lockedDefect.reportedbylist[0].attachmentlist = new CFileAttachment[1];
lockedDefect.reportedbylist[0].attachmentlist[0] = file;
}
// Save our changes.
cgiengine.saveDefect(lSession, lockedDefect);
}
}
Here is the modified method that allowed me to attach a PDF to SOAP and get it into TestTrack as an attachment to an issue:
public void getAttachments(long lSession, CDefect def)
{
ttsoapcgi cgiengine = new ttsoapcgi();
// Lock the defect for edit.
CDefect lockedDefect = cgiengine.editDefect(lSession, def.recordid, "", false);
string attachment = "c:\\TEST\\TEST_PDF.PDF";
CFileAttachment file = new CFileAttachment();
file.mpFileData = File.ReadAllBytes(attachment);
file.mstrFileName = Path.GetFileName(attachment);
CReportedByRecord reprec = lockedDefect.reportedbylist[0];
CFileAttachment[] afile = reprec.attachmentlist;
if (afile == null)
{
lockedDefect.reportedbylist[0].attachmentlist = new CFileAttachment[1];
lockedDefect.reportedbylist[0].attachmentlist[0] = file;
}
// Save our changes.
cgiengine.saveDefect(lSession, lockedDefect);
}
Related
I'm having trouble downloading a file with content using a Powerpoint presentation library (Syncfusion). The docs only supply ASP examples, no Web API specifically.
I can save a file to the file system which has the context I add to the Powerpoint.
I can get the API to download a file to the users browser but this Powerpoint is empty.
Syncfusion has a function to save the Powerpoint to a memory stream so I guess my question is what is the correct way to save a file to the users browser with the content from the stream?
I'm using HTTPGet and hitting the link through the browser. Do I need to sent the context-type or anything like that?
Thanks for your help, I can provide what I have so far if that helps.
Kurtis
Edit:
[HttpGet, Route("")]
public HttpResponseMessage Get()
{
var presentation = Presentation.Create();
var firstSlide = presentation.Slides.Add(SlideLayoutType.Blank);
var textShape = firstSlide.AddTextBox(100, 75, 756, 200);
var paragraph = textShape.TextBody.AddParagraph();
paragraph.HorizontalAlignment = HorizontalAlignmentType.Center;
var textPart = paragraph.AddTextPart("Kurtis' Presentation");
textPart.Font.FontSize = 80;
var memoryStream = new MemoryStream();
presentation.Save(memoryStream);
var result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(memoryStream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "export.pptx"
};
return result;
}
This is what I have, the library saves the presentation to the memory stream, you can change the parameter to a string which writes this to a file and there is an option to pass a filename, format and HttpResponse for MVC but I couldn't get this working with my API controller. I kept getting a network error but didn't know why.
Thanks again
I found my problem with the help of others in the comments.
The code above work but I needed to reset the stream position to zero to actually write the data.
memoryStream.Position = 0;
Thanks for those who commented. :-)
my client wants me to do one task. which is whenever I print ctrl+P from the browser it will go automatically that contents to the database which is sql.
Now, Let me explain what I have tried to achieve this. Usually printerPlusPlus which is third party tool. Which adds virtual printer and prints the files PS to the temp directory than I can read the contents of that postscript file and save it to the database.
My real question is there anything from which I can convert this post script files to text or read them and save the texts to the database?
Or is there any better way to achieve this task?
Ghostscript is the alternate and ow-some feature to convert the postscripts to the text or pdf. But, I am completely clueless about the documentation and how to execute their commands.
_viewer.Interpreter.RunFile("C:\\PrinterPlusPlus\\Temp\\ankit_SONY-VAIO_sony_20151227_185020_3.ps");
GhostscriptPngDevice dev = new GhostscriptPngDevice(GhostscriptPngDeviceType.Png16m);
dev.GraphicsAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.TextAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.ResolutionXY = new GhostscriptImageDeviceResolution(96, 96);
dev.InputFiles.Add(#"C:\\PrinterPlusPlus\\Temp\\ankit_SONY-VAIO_sony_20151227_185020_3.ps");
dev.OutputPath = #"C:\\PrinterPlusPlus\\Temp\\ankit_SONY-VAIO_sony_20151227_185020_3.txt";
dev.Process();
_preview.Activate();
I tried this but this seems to be not working and adding ASCII text to the txt file.
I found ghostscript little confusing. But, I found the solution from here
string inputFile = #"E:\gss_test\test_postscript.ps";
GhostscriptPipedOutput gsPipedOutput = new GhostscriptPipedOutput();
// pipe handle format: %handle%hexvalue
string outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2");
using (GhostscriptProcessor processor = new GhostscriptProcessor())
{
List<string> switches = new List<string>();
switches.Add("-empty");
switches.Add("-dQUIET");
switches.Add("-dSAFER");
switches.Add("-dBATCH");
switches.Add("-dNOPAUSE");
switches.Add("-dNOPROMPT");
switches.Add("-sDEVICE=pdfwrite");
switches.Add("-o" + outputPipeHandle);
switches.Add("-q");
switches.Add("-f");
switches.Add(inputFile);
try
{
processor.StartProcessing(switches.ToArray(), null);
byte[] rawDocumentData = gsPipedOutput.Data;
//if (writeToDatabase)
//{
// Database.ExecSP("add_document", rawDocumentData);
//}
//else if (writeToDisk)
//{
// File.WriteAllBytes(#"E:\gss_test\output\test_piped_output.pdf", rawDocumentData);
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
gsPipedOutput.Dispose();
gsPipedOutput = null;
}
}
This reads the postscript files easily :)
I'm running the below code in my controller in an asp.net mvc project. I want to enable the user to view or download the files that I store on Cloud Files on rackspace.
var identity =
new CloudIdentity()
{
Username = "username",
APIKey = "apikey"
};
var storage = new CloudFilesProvider(identity);
Stream jpgStream = new MemoryStream();
storage.GetObject("files.container", "1.jpg", jpgStream);
Stream pdfStream = new MemoryStream();
storage.GetObject("files.container", "2.pdf", pdfStream);
var jpgResult = File(jpgStream, "Image/jpg", "1.jpg");
var pdfResult = File(pdfStream, "Application/pdf", "2.pdf");
The above code works when I return pdfResult. I get the correct file. But when I return the jpgResult, the browser downloads 1.jpg as an empty 0KB file.
Am I doing this the right way? Any idea what the problem might be?
Problem solved after I added:
jpgStream.Position = 0;
pdfStream.Position = 0;
Before the File() call. As per the question: File is empty and I don't understand why. Asp.net mvc FileResult
I don't know why this wasn't an issue with the pdf file.
You can also use the GetObjectSaveToFile method.
I am working on a printing feature where GUI applications create & store XPS files to be printed in a temp directory and spawn a new C# program which picks these files & sends them to printer.
I need to show the printdialog in the GUI application as the xps file generation process needs some input like page range from user specified settings in print dialog page.
Then the GUI invokes the C# "MyPrinter" process which actually prints the xps files. I am able to transfer PrintTicket settings by serializing them to a file from GUI (through SaveTo API) and reading it from "MyPrinter" process. Sample code at MyPrinter process -
var server = new PrintServer(#"\\servername"); // need to get this from GUI processs
var printQueue = server.GetPrintQueue("printername"); // We can use printQueue name here
printQueue.UserPrintTicket = GetPrintTicket();
int index = 0;
foreach (var printFileName in new DirectoryInfo(printingPath).EnumerateFiles("*.xps"))
{
printQueue.AddJob(string.Format("CustomPrint-{0}", ++index), printFileName.FullName, printQueue.IsXpsDevice);
}
private PrintTicket GetPrintTicket()
{
var reader = new FileStream(#"C:\temp\printTicket.xml", FileMode.Open);
var ticket = new PrintTicket(reader);
reader.Close();
return ticket;
}
Wanted to know -
If there is way to serialize the printQueue settings to a file (need print server and printer name at bare minimum) ? Already tried using Xamlreader/XamlWriter but it seems PrintQueue class does not have a default constructor.
OR
Any other way I could reliably transfer selected printer settings from one application to another ?
Thanks in advance
Amit
I suggest that you have a read of the Serialization (C# and Visual Basic) page from MSDN. In .NET, you can make practically any class serializable simply, using the SerializableAttribute Class like this:
[Serializable] // <--- This is all you need
public class YourClass
{
...
}
You can find several code examples describing how to save a serialized class in the Basic Serialization page on MSDN... from this linked page:
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write,
FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
I used following way to transfer print settings & print using another process -
Serialized PrintTicket class, it already has "ToXml()" method.
Transferred the printername
For actual printing in the "MyPrinter" process, did the following-
var server = new PrintServer(printDialog.PrintQueue.HostingPrintServer.Name);
var printQueue = server.GetPrintQueue(printDialog.PrintQueue.Name);
printQueue.UserPrintTicket = GetPrintTicket();
PrintUsingXpsDocWriter(printQueue);
}
private void PrintUsingXpsDocWriter(PrintQueue printQueue)
{
var docWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
int index = 0;
foreach (var printFileName in new DirectoryInfo(printingPath).EnumerateFiles("*.xps"))
{
}
printQueue.Dispose();
}
private PrintTicket GetPrintTicket()
{
// This file had serialized print ticket settings
var reader = new FileStream(#"C:\temp\printTicket.xml", FileMode.Open);
var ticket = new PrintTicket(reader);
reader.Close();
return ticket;
}
Thanks
I am getting a error while opening using a presentation (PPTX files) creation code.
Code i am using is given below:
public static void UpdatePPT()
{
const string presentationmlNamespace = "http://schemas.openxmlformats.org/presentationml/2006/main";
const string drawingmlNamespace = "http://schemas.openxmlformats.org/drawingml/2006/main";
string fileName = Server.MapPath("~/PPT1.pptx"); //path of pptx file
using (PresentationDocument pptPackage = PresentationDocument.Open(fileName, true))
{
} // Using pptPackage
}
and the error i am getting is:
"The document cannot be opened because there is an invalid part with an unexpected content type.
[Part Uri=/ppt/printerSettings/printerSettings1.bin],
[Content Type=application/vnd.openxmlformats-officedocument.presentationml.printerSettings],
[Expected Content Type=application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings]."
error occurs at using (PresentationDocument pptPackage = PresentationDocument.Open(fileName, true))
Code works fine for many PPTX files. But it is throwing this error on some files.
I am not able to find any solution.
Thanks for your help.
Old post, but I ran in to the same problem. I solved it programatically.
Means:
My code runs using (var document = PresentationDocument.Open(fileName, true))
If this run into a exception I have a document like described. Then I call FixPowerpoint() method and do the other stuff after again.
Here is the method to share (using System.IO.Packaging):
private static void FixPowerpoint(string fileName)
{
//Opening the package associated with file
using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite))
{
//Uri of the printer settings part
var binPartUri = new Uri("/ppt/printerSettings/printerSettings1.bin", UriKind.Relative);
if (wdPackage.PartExists(binPartUri))
{
//Uri of the presentation part which contains the relationship
var presPartUri = new Uri("/ppt/presentation.xml", UriKind.RelativeOrAbsolute);
var presPart = wdPackage.GetPart(presPartUri);
//Getting the relationship from the URI
var presentationPartRels =
presPart.GetRelationships().Where(a => a.RelationshipType.Equals("http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings",
StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();
if (presentationPartRels != null)
{
//Delete the relationship
presPart.DeleteRelationship(presentationPartRels.Id);
}
//Delete the part
wdPackage.DeletePart(binPartUri);
}
wdPackage.Close();
}
}
Finally i have solved my problem. The PPTX i got was developed in mac os. So what i did is i just opened a working pptx file. And copied all the contents of not working pptx into working pptx and saved it by the name of not working pptx.