How to change the permission level, download file - c#

I try to create a web browser. Currently I try to realize a function that if the user wants to download some file an additional window is shown with a list of already downloaded files. If the file has already been loaded, a message is shown (just an idea).
So far, I get a link to the file location in the main form and send it to the other form:
DownLoadFile dlf = new DownLoadFile();
...
WebBrowser wb = new WebBrowser();
wb.Navigating += new WebBrowserNavigatingEventHandler(wb_Navigating);
...
private void wb_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
...
if (e.Url.ToString().EndsWith(".mp3"))
{
dlf.DownloadPath = e.Url;
dlf.Show();
}
}
In the new form I try to use this link for file downloading:
public Uri DownloadPath { get; set; }
...
private void DownLoadFile_Load(object sender, EventArgs e)
{
string filePath = null;
//get FileName from URL
string[] ArrayForName;
ArrayForName = DownloadPath.ToString().Split('/');
saveFileDialogFile.FileName =
ArrayForName[ArrayForName.Length-1].Replace("%"," ").Trim();
if (saveFileDialogFile.ShowDialog() == DialogResult.OK)
{
WebClient client = new WebClient();
//get Url
Uri url = new Uri(DownloadPath.ToString());
//get place where want to save with default name
filePath = saveFileDialogFile.FileName;
//event for result
client.DownloadFileCompleted +=
new System.ComponentModel.AsyncCompletedEventHandler (client_DownloadFileCompleted);
//download
client.DownloadFileAsync(url, filePath);
}
}
void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
MessageBox.Show("Compleated");
}
My questions are:
Regarding if (e.Url.ToString().EndsWith(".mp3")) - How can i
change this for knowing not only when the user tries to download mp3 file,
but all types of files - maybe there is a better way
If i want to download a file using some link directly, I get the message "Currently you have not required permission for that" - How can I
change permission level for my web browser
If i finally get a link to the file and start to download it, as result just name of file (size of file 0 kb) - where i'm wrong.

my solution (maybe not the best one)
create event for webBrowser
wb.Navigating += new WebBrowserNavigatingEventHandler(wb_Navigating);
and in this event use next
if (GetWorkingWebBrowser().StatusText != null)
{
try
{
WebRequest request = WebRequest.Create(GetWorkingWebBrowser().StatusText);
request.Method = "HEAD";
using (WebResponse response = request.GetResponse())
{
if (response.ContentLength > 0 &&
!response.ContentType.ToString().ToLower().Contains("text/html"))
{
dlf.DownloadPath = e.Url; //move url to my form for dwnload
dlf.Show(); //show form
}
}
}
catch (UriFormatException)
{
}
catch (WebException)
{
}
}
GetWorkingWebBrowser() - method that return current active webBrowser on tab, meas webBrowser

Related

non-invocable member PictureBox.ImageLocation cannot be used like a method

I am working with the Windows Forms app. It connects to the Flikr website via free API key, searches images that I provide through the textBox and displays the names of the files that correspond to the keyword in the imagesListBox. When I click on the image name in the imagesListBox the image is displayed inside of the pictureBox. Now I am trying to save an image from the pictureBox and I get this error: "non-invocable member PictureBox.ImageLocation cannot be used like a method". Is there another method similar to ImageLocation which I can use to retrieve the image url address? Here is my code for the button which is supposed to save the image:
private void btnSave_Click(object sender, EventArgs e)
{
//method of saving image
try
{
if (pictureBox.Image != null)
{
//5
string filePath = PictureBox.ImageLocation();
string fileName = Path.GetFileName(filePath);
File.Copy(pictureBox.Text, Path.Combine(#"C:\", Path.GetFileName(pictureBox.Text)), true);
MessageBox.Show("The image has been saved to C drive.");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
Searching and uploading images from Flikr:
private async void searchButton_Click(object sender, EventArgs e)
{
// if flickrTask already running, prompt user
if (flickrTask?.Status != TaskStatus.RanToCompletion)
{
var result = MessageBox.Show(
"Cancel the current Flickr search?",
"Are you sure?", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
// determine whether user wants to cancel prior search
if (result == DialogResult.No)
{
return;
}
else
{
flickrClient.CancelPendingRequests(); // cancel search
}
}
// Flickr's web service URL for searches
var flickrURL = "https://api.flickr.com/services/rest/?method=" +
$"flickr.photos.search&api_key={KEY}&" +
$"tags={inputTextBox.Text.Replace(" ", ",")}" +
"&tag_mode=all&per_page=500&privacy_filter=1";
imagesListBox.DataSource = null; // remove prior data source
imagesListBox.Items.Clear(); // clear imagesListBox
pictureBox.Image = null; // clear pictureBox
imagesListBox.Items.Add("Loading..."); // display Loading...
// invoke Flickr web service to search Flick with user's tags
flickrTask = flickrClient.GetStringAsync(flickrURL);
// await flickrTask then parse results with XDocument and LINQ
XDocument flickrXML = XDocument.Parse(await flickrTask);
// gather information on all photos
var flickrPhotos =
from photo in flickrXML.Descendants("photo")
let id = photo.Attribute("id").Value
let title = photo.Attribute("title").Value
let secret = photo.Attribute("secret").Value
let server = photo.Attribute("server").Value
let farm = photo.Attribute("farm").Value
select new FlickrResult
{
Title = title,
URL = $"https://farm{farm}.staticflickr.com/" +
$"{server}/{id}_{secret}.jpg"
};
// clear imagesListBox
imagesListBox.Items.Clear();
// set ListBox properties only if results were found
if (flickrPhotos.Any())
{
imagesListBox.DataSource = flickrPhotos.ToList();
imagesListBox.DisplayMember = "Title";
}
else // no matches were found
{
imagesListBox.Items.Add("No matches");
}
}
Since it has been asked how I get images inside the pictureBox:
// display selected image
private async void imagesListBox_SelectedIndexChanged(
object sender, EventArgs e)
{
if (imagesListBox.SelectedItem != null)
{
string selectedURL = ((FlickrResult)imagesListBox.SelectedItem).URL;
// use HttpClient to get selected image's bytes asynchronously
byte[] imageBytes = await flickrClient.GetByteArrayAsync(selectedURL);
// display downloaded image in pictureBox
using (var memoryStream = new MemoryStream(imageBytes))
{
pictureBox.Image = Image.FromStream(memoryStream);
}
}
}
Change the line to the following. ImageLocation is a property, not a method.
string filePath = pictureBox.ImageLocation;

WebBrowser causes program out of memory error

I have a Windows Desktop application that is used to do WebScraping on a website using WebBrowser.
I had to use WebBrowser because the website implements some Javascript function so that was the only way to get the html content of the pages.
The program has to parse about 1500 pages so I have implemented a task delay in order to avoid to overload the server ( and may be getting banned ).
The problem is that after 50-100 parsed pages, I get an out of memory error and the program gets closed.
This is the code:
private async void buttonProd_Click(object sender, EventArgs e)
{
const string C_Prod_UrlTemplate = "http://www.mysite.it";
var _searches = new List<Get_SiteSearchResult>();
using (ProdDataContext db = new ProdDataContext())
{
_searches = db.Get_SiteSearch("PROD").ToList();
foreach (var s in _searches)
{
WebBrowser wb1 = new WebBrowser();
wb1.ScriptErrorsSuppressed = true;
Uri uri = new Uri(String.Format(C_Prod_UrlTemplate,s.prod));
wb1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
wb1.Url = uri;
await Task.Delay(90 * 1000);
}
}
}
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
using (ProdDataContext db = new ProdDataContext())
{
WebBrowser wb = (WebBrowser)sender;
string s = wb.Document.Body.InnerHtml;
string fName = wb.CodSite + "_" + wb.PostId + ".txt";
File.WriteAllText(wb.FolderPath + #"LINKS\" + fName, s);
db.Set_LinkDownloaded(wb.CodSite, wb.PostId);
}
}
The error messa is generated on this command line in webBrowser_DocumentCompleted method:
string s = wb.Document.Body.InnerHtml;
Thanks to support
Instead of using a control (which is a rather complex construct that requires more memory than a simple object), you can simply fetch the string (the HTML code only) associated with an URL like this:
using(WebClient wc = new WebClient()) {
string s = wc.DownloadString(url);
// do stuff with content
}
Of course, you should ensure some error handling (maybe even a retrial mechanism) and put some delays to ensure you are not doing too much requests per time interval.

load image from PC as stream

I am trying to load a picture from my PC as a raw image in order to use it with the Microsoft cognitive services emotion (UWP).
below is a piece of my code:
//Chose Image from PC
private async void chosefile_Click(object sender, RoutedEventArgs e)
{
//Open Dialog
FileOpenPicker open = new FileOpenPicker();
open.ViewMode = PickerViewMode.Thumbnail;
open.SuggestedStartLocation = PickerLocationId.Desktop;
open.FileTypeFilter.Add(".jpg");
open.FileTypeFilter.Add(".jpeg");
open.FileTypeFilter.Add(".gif");
open.FileTypeFilter.Add(".png");
file = await open.PickSingleFileAsync();
if (file != null)
{//imagestream is declared as IRandomAccessStream.
imagestream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var image = new BitmapImage();
image.SetSource(imagestream);
imageView.Source = image;
}
else
{
//
}
}
The part above works fine, it selects a photo from the pc (dialog box) and displays it in Image box.
private async void analyse_Click(object sender, RoutedEventArgs e)
{
try
{
emotionResult = await emotionServiceClient.RecognizeAsync(imagestream.AsStream());
}
catch
{
output.Text = "something is wrong in stream";
}
try {
if(emotionResult!= null)
{
Scores score = emotionResult[0].Scores;
output.Text = "Your emotions are: \n" +
"Happiness: " + score.Happiness + "\n" +
"Sadness: " + score.Sadness;
}
}
catch
{
output.Text = "Something went wrong";
}
}
I think the error is due to imagestream.AsStream()
imagestream is declared as IRandomAccessStream.
Can someone please tell me how to fix that part and if the error is in fact due to not loading the image correctly?
EDIT:
Also is there a better way to do this, instead of using stream to pass the emotionServiceClient a saved file instead of a stream?
Your problem is that you've advanced the stream position by virtue of creating the BitmapImage, so your read position is at the end by the time you call emotionServiceClient.RecognizeAsync. So you'll need to 'rewind':
var stream = imagestream.AsStreamForRead();
stream.Position = 0;
emotionResult = await emotionServiceClient.RecognizeAsync(stream);
Why not use their example, instead of trying to hold the file in memory, why don't you hold a path, and then use the path to read the stream at the time.
https://www.microsoft.com/cognitive-services/en-us/Emotion-api/documentation/GetStarted
In there example;
using (Stream imageFileStream = File.OpenRead(imageFilePath))
{
//
// Detect the emotions in the URL
//
emotionResult = await emotionServiceClient.RecognizeAsync(imageFileStream);
return emotionResult;
}
So you would be capturing imageFilePath as the result of the open file dialog.

How to know if a url is valid for navigating in webbrowser winforms

I'm making a web browser in windows form application based on webbrowser control.
I'm trying to make the url address textbox for 2 purposes : for navigating and for searching , as in chrome for example .
I added this code :
try
{
Uri urlResult = new Uri(urlText.Text);
webbrowser1.Navigate(urlText.Text);
}
catch
{
webbrowser1.Navigate("http://google.com/search?q=" + urlText.Text);
}
the problem is that when I enter "youtube.com" for example , this can not be a Uri so I get this in google
How to perform this ?
any other suggestions are welcomed
thanx in advance
Problem : in your current code you are not checking wether the URL is valid or not.you need to first verify wether the given url is reachable or not.
Solution: create a seperate function to verify the reachbility of the url if it succeeds then Navigate to the url otherwise open it in google.
Try This:
using using System.Net;
private void button3_Click_1(object sender, EventArgs e)
{
string url = string.Empty;
string urlProtocol = "http://"; //or https
if (!urlText.Text.Trim().Contains(urlProtocol))
url = urlProtocol + urlText.Text;
else
url = urlText.Text;
if (CheckURL(url))
{
Uri urlResult = new Uri(url);
webbrowser1.Navigate(url);
}
else
{
webbrowser1.Navigate("http://google.com/search?q=" + urlText.Text);
}
}
bool CheckURL(string url)
{
var req = (HttpWebRequest)HttpWebRequest.Create(url);
bool isURLValid = false;
req.AllowAutoRedirect = false;
try
{
using (var resp = req.GetResponse())
{
var location = resp.Headers["Location"];
if (!String.IsNullOrEmpty(location))
{
isURLValid = true;
}
}
}
catch
{
isURLValid = false;
}
return isURLValid;
}

DownloadFileAsync in loop with CompletedEvent gets only the last file

I'm getting several file links from a file into a loop statement and for each link , I have to download the file , when the download was completed I have to do something with each file.
Here is my code,
foreach(//condition ) {
Descarcare = new WebClient();
Descarcare.DownloadProgressChanged += Descarcare_DownloadProgressChanged;
Descarcare.DownloadFileAsync(new Uri(nod.SelectSingleNode("DownloadLink").InnerText), Directory.GetCurrentDirectory()+);
Descarcare.DownloadFileCompleted +=Descarcare_DownloadFileCompleted;
}
void Descarcare_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
//extract the file
}
But somehow , the webclient downloads the files but the DownloadFileCompleted event fires only for the last downloaded file instead of doing it for each file.
What can cause this?
You are creating a new WebClient in every iteration of your foreach-loop. The best approach is to create a Queue with all files and start a new download in each DownloadFileCompleted until you got all the files you want.
var _downloadQueue = new Queue<Uri>();
var _webClient = new WebClient();
//in your constructor:
_webClient.DownloadProgressChanged += Descarcare_DownloadProgressChanged;
_webClient.DownloadFileCompleted += Descarcare_DownloadFileCompleted;
private void Foo()
{
//...
foreach(/* condition */)
{
_downloadQueue.Enqueue(
new Uri(nod.SelectSingleNode("DownloadLink").InnerText)
);
}
DownloadNext();
}
private void DownloadNext()
{
if(_downloadQeue.Count> 0)
{
_webClient.DownloadFileAsync(
_downloadQueue.Dequeue(), Directory.GetCurrentDirectory()
);
}
}
void Descarcare_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
DownloadNext();
//extract the file
//...
}

Categories

Resources