Faster way to achieve document conversion/preview task - docx

I created win forms app to convert docx to html using pandoc, and a web browser control
to display the html file. This application is much needed for my colleagues in the university,
to preview docx files since we dont have MS Office access any more...
I tested this at my PC and it is working fine on each item click in the listbox,
it loads the preview in webbrowser quicky. But I just want to make it more quick, is there
any recommendations to make it faster (I can provide full code if needed), but the following
is the main listbox selected item changed event:
Also tell me which one is faster from: setting wb.DocumentText as blank or navigate it to about:blank page
private void lbFiles_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
wb.DocumentText = "";
// Two string lists
SelectedFile = AllFiles[lbFiles.SelectedIndex];
NameOnly = AllNamesOnly[lbFiles.SelectedIndex];
if (NameOnly.EndsWith(".txt") || NameOnly.EndsWith(".docx"))
{
#region MediaFolder
if (Directory.Exists("MF")) Directory.Delete("MF", true);
Directory.CreateDirectory("MF");
#endregion
string cmd = "pandoc --extract-media ./MF \"" + SelectedFile + "\" -o " + "output.html";
File.WriteAllText("BatchFile.bat", cmd);
StartHidden("BatchFile.bat"); //Process object with: ProcessWindowStyle.Hidden; and with 3 seconds exit wait
wb.Navigate(Environment.CurrentDirectory + "\\" + "output.html");
}
}
catch(Exception ex) { throw ex; }
}

I tried hard with various solutions.
Most of them were not free, so were not useable, using pendoc as in OP, was not
feasible since it doesn't support the variety of fonts and formats
After going through many possible alternatives (Gembox, Spire.Doc, etc.),
I finally moved to Syncfusion community edition it is already free and its libraries allow to convert all major word processor based formats and its result was same as other non-free solutions. And works faster then pandoc.
Another thing to note is, I switched from WebBrowser to CefSharp as well, as its faster and lighter than WebBrowser, and it works better for pdf file
previews in browser (you can use zoom level, page number as part of URL)

Related

Understanding the JIT; slow website

First off, this question has been covered a few times (I've done my research), and, for example, on the right side of the SO webpage is a list of related items... I have been through them all (or as many as I could find).
When I publish my pre-compiled .NET web application, it is very slow to load the first time.
I've read up on this, it's the JIT which I understand (sort of).
The problem is, after the home page loads (up to 20 seconds), many other pages load very fast.
However, it would appear that the only reason they load is because the resources have been loaded (or that they share the same compiled dlls). However, some pages still take a long time.
This indicates that maybe the JIT needs to compile different pages in different ways? If so, and using a contact form as an example (where the Thank You page needs to be compiled by the JIT and first time is slow), the user may hit the send button multiple times whilst waiting for the page to be shown.
After I load all these pages which use different models or different shared HTML content, the site loads quickly as expected. I assume this issue is a common problem?
Please note, I'm using .NET 4.0 but, there is no database, XML files etc. The only IO is if an email doesn't send and it writes the error to a log.
So, assuming my understanding is correct, what is the approach to not have to manually go through the website and load every page?
If the above is a little too broad, then can this be resolved in the settings/configuration in Visual Studio (2012) or the web.config file (excluding adding compilation debug=false)?
In this case, there are 2 problems
As per rene's comments, review this http://msdn.microsoft.com/en-us/library/ms972959.aspx... The helpful part was to add the following code to the global.asax file
const string sourceName = ".NET Runtime";
const string serverName = ".";
const string logName = "Application";
const string uriFormat = "\r\n\r\nURI: {0}\r\n\r\n";
const string exceptionFormat = "{0}: \"{1}\"\r\n{2}\r\n\r\n";
void Application_Error(Object sender, EventArgs ea) {
StringBuilder message = new StringBuilder();
if (Request != null) {
message.AppendFormat(uriFormat, Request.Path);
}
if (Server != null) {
Exception e;
for (e = Server.GetLastError(); e != null; e = e.InnerException) {
message.AppendFormat(exceptionFormat,
e.GetType().Name,
e.Message,
e.StackTrace);
}
}
if (!EventLog.SourceExists(sourceName)) {
EventLog.CreateEventSource(sourceName, logName);
}
EventLog Log = new EventLog(logName, serverName, sourceName);
Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
//Server.ClearError(); // uncomment this to cancel the error
}
The server was maxing out during sending of the email! My code was fine, but, viewing Task Scheduler showed it was hitting 100% memory...
The solution was to monitor the errors shown by point 1 and fix it. Then, find out why the server was being throttled when sending an email!

Selenium and wordpress: New post test

I've been looking a bit at Selenium, and I'm beginning to like it, since I know some Java programming and find both Java and C# pretty straight-forward for simple things like this.
However, I'm struggling with a test that creates a new post in Wordpress, from the Dashboard page:
This is the Selenium code (in C#):
(The Driver instance is, obviously, a driver class I've created - for starting the browser and connecting to the wordpress site.)
1: Driver.Instance.FindElement(By.Id("title)).SendKeys(title);
2: Thread.Sleep(1000);
3:
4: Instance.SwitchTo().Frame("content_ifr");
5: Thread.Sleep(1000);
6:
7: Driver.Instance.SwitchTo().ActiveElement().SendKeys("something");
Now, what happens is that the title is easily found (by ID, so I wouldn't expect problems there), and I can easily insert the title text (line 1).
But the inline frame for the post body is causing problems. When running the test, after the topic is filled in, the cursor changes to the body area (line 4) - as planned. However, nothing more happens. The SendKeys("string") method (ine 7) doesn't seem to work there.
Any ideas?
EDIT: Of course - an important piece of information is that the iframe in Wordpress simply loads a TinyMCE editor. So, in the page source, there's only a body tag with the javascript loading of the editor.
EDIT2: Of course, something suddenly changed. Without ANY change to the wordpress page, the "content_ifr" is now suddenly missing (?!!!!!?) The Selenium test fails with "unable to locate frame...", and it's also suddenly missing from the page source.
EDIT3: I also noticed something:
Driver.Instance.SwitchTo().Frame(iframe);
Driver.Instance.FindElement(By.Id("tinymce")).SendKeys("message body");
It's the SECOND line that makes the cursor switch to the mce field, not the line with the .SwitchTo(). However, I need the first line - the second line does nothing on its own. This is approaching something really stupid. I've been looking for a solution to this for a week - this doesn't exactly bode well for Selenium. The Selenium user group doesn't even want to answer when I ask them.
Also - if I skip the SendKeys() method in the second line, nothing happens. So, it seems that the two lines does ALLMOST what it should, right up to and including placing the cursor in the correct spot. But it never sends any text.
EDIT4 (last): After actually figuring out how to use IJavaScriptExecutor, it works using the solution(s) below.
Java method to handle TinyMCE editor would look like:
public void entersTopicOfBody(String textToBeTyped, WebDriver driver) {
driver.switchTo().frame("content_ifr");
WebElement body = driver.findElement(By.xpath("//body"));
body.click();
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].innerHTML = '"+ textToBeTyped+"'", body);
driver.switchTo().defaultContent();
}
Below is some C# code that publishes a post. I think the main issues you have are due to timing issues.
I've done a bit of Selenium recently and I favour implicit waits: it waits for a maximum time period for the item to be available, but returns as soon as possible. So you can specify a max wait of 100 seconds, but if it finds it in 1 second, it will only wait 1 second. Much more efficient vs sleeping for an arbitrary length of time. See this post about Implicit and Explicit waits
But even with implicit waits, it may not solve all issues. When coding the sample below, I ran into the issue where the "Publish" button was disabled and re-enabled after some time. And that's when you have to look at the code to see what it is doing as well. It's times such as these where sleeps can help you fix the problem for a quick fix if you do not wish to debug too much: just be sure to set a large enough sleep time and be wary that it could be inconsistent in the future.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Support.Events;
namespace SeleniumTest
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new OpenQA.Selenium.Firefox.FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
// enter your configurations here
driver.Navigate().GoToUrl("http://localhost/wordpress/wp-admin/post-new.php");
driver.FindElement(By.Id("user_login")).SendKeys("admin");
driver.FindElement(By.Id("user_pass")).SendKeys("yourpassword");
driver.FindElement(By.Id("wp-submit")).Click();
driver.FindElement(By.Id("title")).SendKeys("the title");
var iframe = driver.FindElement(By.Id("content_ifr"));
driver.SwitchTo().Frame(iframe);
// your solution which works in my instance
//driver.SwitchTo().ActiveElement().SendKeys("hello tiny mce from selenium");
// send keys with exact element
//driver.FindElement(By.Id("tinymce")).SendKeys("hello tiny mce from selenium");
// javascript - 1
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
var tinymce = driver.FindElement(By.Id("tinymce"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].innerHTML = 'hello tiny mce via javascript'", tinymce);
// javascript - 0
driver.SwitchTo().DefaultContent();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(11));
wait.Until((d) => { return !d.FindElement(By.Id("publish")).GetAttribute("class").Contains("disabled"); }); // wait for publish button to be enabled
driver.FindElement(By.Id("publish")).Click();
driver.FindElement(By.Id("message")); // wait for message on next page to verify it is posted
driver.Close();
}
}
}
A PHP version of olyv solution:
$content = 'my text';
$this->frame( 'content_ifr' );
$body = $this->byXPath( '//body' );
$body->click();
$script = 'arguments[0].innerHTML = "" + arguments[1] + ""; ';
$this->execute( [
'script' => $script,
'args' => [ $body->toWebDriverObject(), $content ],
]
);
$this->frame( null );
I know that I am a bit late to the party, but I just found a solution that is (I believe) much simpler than the answers given so far. So I decided to post it here in case it could help someone else.
There is no need to switch frames here. What you wanna do is 'click' on the button in the top right corner of the text editor that says "Text", which has id = "content-html". Now, you can 'send keys" to the textarea, which has id = "content".
Here is some Python code that does just this:
driver.find_element_by_id("content-html").click()
driver.find_element_by_id("content").send_keys("Some text...")
Hope it helps

Powerpoint Conversion to JPEG with ASP.NET?

I have a client in need of an application that uploads a powerpoint file to a web app that can display the slides as jpegs (or flash, silverlight, HTML, video.. any format really) using ASP.NET.
I built the application with MVC in VS 2010 using Office developer tools but the clients server does not have Powerpoint and it seems the Microsoft.Office.Interop.Powerpoint assembly won't function if it can't call Powerpoint on the host machine.
I've looked at every possible discussion dealing with this, the majority conclude its bad practice to even have Powerpoint deployed on a server, so my question is does anyone know of a utility that can convert PPT slide to JPG or Flash or anything to present the slides on a website?
Here it is with the use of Interop object..
private void mConvertPPT_To_Images(string sPPTFilePath, string sImagesDirectoryPath)
{
try
{
Microsoft.Office.Interop.PowerPoint.Application appPpt = new Microsoft.Office.Interop.PowerPoint.Application();
Microsoft.Office.Interop.PowerPoint.Presentation objActivePresentation
= appPpt.Presentations.Open(sPPTFilePath,
Microsoft.Office.Core.MsoTriState.msoCTrue,
Microsoft.Office.Core.MsoTriState.msoTriStateMixed,
Microsoft.Office.Core.MsoTriState.msoFalse);
//objActivePresentation.SaveAs(sImagesDirectoryPath, PpSaveAsFileType.ppSaveAsJPG, MsoTriState.msoFalse);
//objActivePresentation.Export(sImagesDirectoryPath + #"\Slide1.png", "png", 960, 720);
//objActivePresentation.SaveAs(sImagesDirectoryPath + "slide", PpSaveAsFileType.ppSaveAsTIF, MsoTriState.msoFalse);
int i = 0;
foreach (Microsoft.Office.Interop.PowerPoint.Slide objSlide in objActivePresentation.Slides)
{
//Names are generated based on timestamp.
//objSlide.Export("Slide" + i, "PNG", 960, 720);
objSlide.Export(sImagesDirectoryPath + #"\Slide" + i + ".GIF", "GIF", 960, 720);
i++;
}
objActivePresentation.Close();
appPpt.Quit();
}
catch (Exception ex)
{
throw;
}
}
There’s a solution by iSpring called iSpring Platform (http://www.ispringsolutions.com/ispring-platform). This is an SDK that allows software using .NET to convert PPT presentations to HTML5 and Flash. It supports all the effects, animations, and other PowerPoint stuff.
P.S. Looked at the post data and realized that the author had probably found the solution. Maybe my answer will be of use for someone else.

Silverlight MediaElement refusing to play audio

I am having the hardest time figuring this problem out. I have a Silverlight 4 application that loads audio and video files from URLs. The URLs are the same domain as the application is hosted on and it works great for video.
The URLs are actually asp.net mvc controllers that are responsible for reading the file from a shared location on and the server and serving back a filestream. The URLs look something like this:
http://localhost:31479/CourseMedia?path=\omnisandbox1\ILMSShare2\Demo-Fire+Behavior\media\Disclaim.wma&encrypted=False&id=00000000-0000-0000-0000-000000000000
If I put the URL directly into the browser the file loads and plays in windows media player just fine, and if I use a separate test silverlight project to load the url it also works, but for the life of me I can not get it to work properly in my main project.
This is the routine I use to actually do the source setting:
protected void SetPlayerURL(MediaElement player, string url)
{
if (player != null && url.Length > 0)
{
player.ClearValue(MediaElement.SourceProperty);
player.Source = new Uri(this.Packet.GetMediaUrl(url, false, Guid.Empty));
}
}
and the GetMediaURL function simply builds the URL format seen above:
public string GetMediaUrl(
string path,
bool encrypted,
Guid key)
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("http://{0}/CourseMedia?path={1}&encrypted={2}&id={3}",
this.Host,
System.Windows.Browser.HttpUtility.UrlEncode(path),
encrypted,
key);
return builder.ToString();
}
The request to the controller is never made for the media when it is audio. Seems odd to me as this exact code works fine for video. The MediaElement state never leaves "Closed" and the CurrentStateChanged,, MediaOpened, and MediaFailed events are never triggered.
I am at a loss!
Try setting ScrubbingEnabled of the MediaElement to false, there were some problems with Framework version 3.5 and audio and the workaround was setting that to false. Might be worth trying.
Also try capturing BufferingStarted, BufferingEnded, MediaEnded along with your MediaFailed and MediaOpened events. I'm curious if it is a buffering issue.

Browse a file from my pc using web application in asp.net

I have a web application which I uploaded using IIS. I want the users using the application would be able to select a file located on their (the user) computer and read its contents.
The code is:
TextReader trs = new StreamReader(faFile.Value);
DataAccessLayer.clearFA();
string line = trs.ReadLine();
// Read all unneeded data
while (line != "** Start Data **")
{
line = trs.ReadLine();
}
line = trs.ReadLine();
while (line != null)
{
string[] words = line.Split('*');
// There is no message
if (words[4] == "")
{
DataAccessLayer.insertIntoFA(Int32.Parse(words[1]), words[3].Replace("'", ""));
}
else
{
DataAccessLayer.insertIntoFA(Int32.Parse(words[1]), words[4].Replace("'", ""));
}
line = trs.ReadLine();
}
}
When I run it from my pc it works. But when I try to run it from the IIS it gives me the following error:
Could not find a part of the path 'C:\Documents and Settings\myUser\Desktop\file.txt'.
I understand that the application cant read the file from the user pc. Any idea how can I make it work?
Thanks!
Greg
This is done for security reasons - a browser does not have access to the filesystem of the user.
There is no way to work around this, as all other technologies running inside a browser are sandboxed and limited (again, for security reasons).
The closest you can get is to use an <input type="file"> that lets the user to select a file for upload.
The upload file's path in IE 8 is a full path. You can obtain filename from the full name. Combine server path and filename before saving file

Resources