C# - FTP Upload Using UploadFileAsync With Progress on Console - c#

I'm new to C# and I wanted to do an FTP upload with progress showing on console. My code is as below from some help from MSDN examples.
using System;
using System.Net;
using System.IO;
using System.Threading.Tasks;
namespace FTPUpload
{
class FTPClient
{
public void Upload()
{
string localFile = #"D:\Applications\python-3.3.0.msi";
string destPath = "ftp://127.0.0.1/python-3.3.0.msi";
if (File.Exists(localFile))
{
Console.WriteLine(localFile + " exists!");
}
else
{
Console.WriteLine(localFile + " doesn't exists!");
}
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential("Anonymous", "Anonymous");
client.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback);
client.UploadFileCompleted += new UploadFileCompletedEventHandler(UploadCompleted);
client.UploadFileAsync(new Uri(destPath), localFile);
Console.WriteLine("Upload started");
}
}
public void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e)
{
Console.WriteLine(e.TotalBytesToSend);
}
public void UploadCompleted(object sender, UploadFileCompletedEventArgs e)
{
Console.WriteLine(e.Result);
}
public static void Main(string[] args)
{
FTPClient ftpClient = new FTPClient();
ftpClient.Upload();
}
}
}
I think I have not written it properly and I tried to search in Google can't find any examples with respect to this.
Kindly point me in right direction.
I have seen this but not able to get the point
File is not uploaded to FTP server on some machines when using WebClient.UploadFileAsync
Thanks!

Related

Continuous Async Ping inside a Windows Service

I need to monitor a list of hosts continuously. After N seconds, i need to check the list again. So, I tried to use the async ping inside a Windows Service.
I tried to follow tips from other posts related to the topic, but always my service stops shortly after starting it.
There are a problem with await in "OnElapsedTime" function.
Any one have an idea what is wrong? Bellow my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Net.NetworkInformation;
namespace PingAsyncService
{
public partial class HyBrazil_Ping : ServiceBase
{
Timer timer = new Timer();
List<string> IPList = new List<string>(); //List of IPs
public HyBrazil_Ping()
{
IPList.Add("192.168.0.1");
IPList.Add("192.168.0.254");
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 5000; //number in miliseconds
timer.Enabled = true;
}
protected override void OnStop()
{
WriteToFile("Service is stopped at " + DateTime.Now);
}
private async void OnElapsedTime(object source, ElapsedEventArgs e)
{
//WriteToFile("Service is recall at " + DateTime.Now);
var ResultList = await PingAsync();
foreach(PingReply reply in ResultList)
{
WriteToFile(reply.Address.ToString() + ";" + reply.Status.ToString());
}
}
private async Task<PingReply> PingAndProcessAsync(Ping pingSender, string ip)
{
var result = await pingSender.SendPingAsync(ip, 2000);
return result;
}
private async Task<List<PingReply>> PingAsync()
{
Ping pingSender = new Ping();
var tasks = IPList.Select(ip => PingAndProcessAsync(pingSender, ip));
var results = await Task.WhenAll(tasks);
return results.ToList();
}
public void WriteToFile(string Message)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
Thanks a lot!
In one of the comments you mentioned the error message as
"An asynchronous call is already in progress. It must be completed or canceled before you can call this method."
Chances are, the Ping object does not let simultaneous asynchronous calls.
Using a new Ping object everytime, on each call, might help as below.
private async Task<List<PingReply>> PingAsync()
{
// Ping pingSender = new Ping();
var tasks = IPList.Select(ip =>
{
using (var p= new Ping())
{
return PingAndProcessAsync(p, ip);
}
});
var results = await Task.WhenAll(tasks);
return results.ToList();
}

Having Issues Using WebClient to Download Files In Unity

So I am having a big issue when coding for Unity. I am very new to C# and so have used examples I have found online to make this code. My only issue is there are no errors popping up but it won't download the file properly.
I am using this code so that it will be easy for my users to import unitypackages they would use often. I have a button that works as intended, it shows download and then changes to import if the file exists. However, if I click it when it says download it will instantly say "Download Complete" and the file won't show up for a few minutes. When it finally does the file is 0KB in size.
I really need help figured out why my file isn't downloading properly. I am super stumped.
This code is the script for the WebClient.
using UnityEngine;
using System.IO;
using System.Net;
using System;
using System.ComponentModel;
using UnityEditor;
namespace SentinelsSDK
{
public class SentinelsSDK_ImportManager
{
private static string localPath = "Assets/VRCSDK/Dependencies/VRChat/Imports/";
private static string localDownloadPath = "Assets/VRCSDK/Dependencies/VRChat/Imports/";
private static string urlStart = "https://www.sentinels.xyz/uploads/2/0/9/0/20909832/";
public static void DownloadAndImportAssetFromServer(string assetName)
{
if (File.Exists(localDownloadPath + assetName))
{
sentLog(assetName + " exists. Importing it..");
importDownloadedAsset(assetName);
}
else
{
sentLog(assetName + " does not exist. Starting download..");
downloadFile(assetName);
}
}
private static void downloadFile(string assetName)
{
WebClient w = new WebClient();
w.Headers.Set(HttpRequestHeader.UserAgent, "Webkit Gecko wHTTPS (Keep Alive 55)");
w.QueryString.Add("assetName", assetName);
w.DownloadFileCompleted += fileDownloadCompleted;
w.DownloadProgressChanged += fileDownloadProgress;
string url = urlStart + assetName;
w.DownloadFileAsync(new Uri(url), localDownloadPath + assetName);
}
private static void fileDownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
string assetName = ((WebClient)(sender)).QueryString["assetName"];
sentLog("Download of file " + assetName + " completed!");
}
private static void fileDownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
sentLog("Progress is at " + e.ProgressPercentage.ToString() + "%");
}
private static void sentLog(string message)
{
Debug.Log("[SentinelsSDK] AssetDownloader: " + message);
}
public static void importAsset(string assetName)
{
AssetDatabase.ImportPackage(localPath + assetName, true);
}
public static void importDownloadedAsset(string assetName)
{
AssetDatabase.ImportPackage(localDownloadPath + assetName, true);
}
}
}
This code is the button calling the download from my other script.
using SentinelsSDK;
...
private static string localDownloadPath = "Assets/VRCSDK/Dependencies/VRChat/Imports/";
...
GUILayout.BeginHorizontal();
if (GUILayout.Button((File.Exists(localDownloadPath + "poiyomitoon.unitypackage") ? "Import" : "Download") + " - Poiyomi Toon"))
{
SentinelsSDK_ImportManager.DownloadAndImportAssetFromServer("poiyomitoon.unitypackage");
}
GUILayout.EndHorizontal();
So I figured out my issue, but I am not sure why it was an issue. Apparently putting "https://" for the urlstart instead of "http://" broke it, despite you being able to download the file normally regardless of the protocol used. If someone can help me figure out why that is I would be grateful!

C# UDP Chat receive no message

I try to write a UDP-Chat in C#.
I have some unexpected behavoir in my Chat Programm, when I start the programm on two different machines connected to the same Network. At the first mashine the programm works fine it can send and recive messages properly, but on the second machine it can just send messages but it can't recive them.
I testet this with a 3rd mashine too(a VM with a bridged networkinterface), but with the same result, it just can send messages without recieving.
is there a error in my code or is it a desing error?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading;
using System.Net.NetworkInformation;
using System.ComponentModel;
using System.Data;
namespace CScharpChat
{
/// <summary>
/// Interaktionslogik für Chat_window.xaml
/// </summary>
public partial class Chat_window : Window
{
string name = "testuser";
UdpClient receiveClient = new UdpClient(1800);
IPEndPoint receiveEndPint = new IPEndPoint(IPAddress.Any, 0);
public Chat_window(string name)
{
this.name = name;
fileWriter("Chat started", false); // write the initial start date in the errorfile
InitializeComponent();
Message_Load(); // starts the listen server theread
}
private void Message_Load()
{
lb_chat.Items.Add(name + " Joined the room...");
Thread rec = new Thread(ReceiveMessageFn);
rec.Start();
}
private void ReceiveMessageFn()
{
try
{
while (true)
{
Byte[] receve = receiveClient.Receive(ref receiveEndPint);
string message = Encoding.UTF8.GetString(receve);
if (message == name + " logged out...")
{
break;
}
else
{
if (message.Contains(name + " says >>"))
{
message = message.Replace(name + " says >>", "Me says >>");
}
ShowMessage(message);
}
}
//Thread.CurrentThread.Abort();
//Application.Current.Shutdown();
}
catch (Exception e)
{
//errorHandler(e);
}
}
private void ShowMessage(string message)
{
if (lb_chat.Dispatcher.CheckAccess())
{
lb_chat.Items.Add(message);// add Item to list-box
lb_chat.ScrollIntoView(lb_chat.Items[lb_chat.Items.Count - 1]);// scroll down to current Item
lb_chat.UpdateLayout();
}
else {
lb_chat.Dispatcher.BeginInvoke(
new Action<string>(ShowMessage), message); // if list-box is not access able get access
return;
}
}
private void tb_eingabe_GotFocus(object sender, RoutedEventArgs e)
{
tb_eingabe.Text = "";
}
private void btn_submit_Click(object sender, RoutedEventArgs e)
{
submit_message();
}
private void tb_eingabe_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
submit_message();
}
}
void submit_message()
{
if (tb_eingabe.Text != "")
{
string data = name + " says >> " + tb_eingabe.Text;
SendMessage(data);
tb_eingabe.Clear(); // clear the textbox-values
tb_eingabe.Focus(); // get focus on tb if the submit button was used, the tb lost the focus
}
}
private void SendMessage(string data)
{
try{
UdpClient sendClient = new UdpClient();
Byte[] message = Encoding.UTF8.GetBytes(data); // use UTF8 for international encoding
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 1800); // use a broadcast with the given port
sendClient.Send(message, message.Length, endPoint);
sendClient.Close();
}
catch (Exception e)
{
errorHandler(e);
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
string data = name + " logged out...";
SendMessage(data); // send a logout message to the other chat peers
}
// debugging functions
static void errorHandler(Exception errorMsg)
{
MessageBox.Show(errorMsg.ToString()); // create a error-message-box
fileWriter(errorMsg.ToString(), true); // call the file-writer function to write the error in a file
}
static void fileWriter(string fileText, bool append)
{
System.IO.StreamWriter file = new System.IO.StreamWriter(".\\Errorfile.txt", append); // locate the error next to the chat.exe
file.WriteLine(GetTime(DateTime.Now) + "\n " + fileText); // append the date
file.Close();
}
public static String GetTime(DateTime val)
{
return val.ToString("yyyyMMddHHmmssffff"); // return the current date as string
}
}
}
Instead of IPAddress.Broadcast(255.255.255.255) provide your local network broadcast address. See the example below:
IPAddress broadcast = IPAddress.Parse("192.168.1.255"); //replace the address with your local network.
IPEndPoint endPoint = new IPEndPoint(broadcast, 11000);
sendClient.Send(message, message.Length, endPoint);
IPAddress.Broadcast doesn't work in some network.

Download multiple files in parallel using c#

I want to download files in parallel using C#. For this, I have written this code which is working perfectly but the problem is that UI is freezing.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace FileDownloader
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private static int count = 1;
private static string f= "lecture";
private string URL = "www.someexample.com";
public MainWindow()
{
InitializeComponent();
}
public static string GetDirectoryListingRegexForUrl(string url)
{
if (url.Equals(URL))
{
return "(?<name>.*)";
}
throw new NotSupportedException();
}
public void DownloadP(string[] urls)
{
Parallel.ForEach(urls.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile);
}
private void DownloadFile(string url)
{
using(WebClient client=new WebClient())
{
if (url.EndsWith(".pdf"))
{
int nextIndex = Interlocked.Increment(ref count);
client.DownloadFile(url, f + nextIndex + ".pdf");
this.Dispatcher.Invoke(() => {
listbox.Items.Add(url);
});
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DownloadP(listofFiles);
}
}
}
You can use async/await with conjunction with new WebClient method DownloadFileTaskAsync.
private async Task DownloadFile(string url)
{
if (!url.EndsWith(".pdf"))
{
return;
}
using (var client = new WebClient())
{
int nextIndex = Interlocked.Increment(ref count);
await client.DownloadFileTaskAsync(url, "lecture" + nextIndex + ".pdf");
listBox.Items.Add(url);
}
}
private async void Button_OnClick(object sender, RoutedEventArgs e)
{
button.IsEnabled = false;
await DownloadFiles(urlList);
button.IsEnabled = true;
}
private async Task DownloadFiles(IEnumerable<string> urlList)
{
foreach (var url in urlList)
{
await DownloadFile(url);
}
}
Relace your DownloadP function with this :
public async Task DownloadP(string[] urls)
{
await Task.Factory.StartNew(() => Parallel.ForEach(urls.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile));
}
instead of using client.DownloadFile use client.DownloadFileAsync like this
var webClient=new WebClient();
webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;
webClient.DownloadFileAsync("Your url","file_name");
the event
private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Download Completed.");
}
I know this Question is old, but WebClient is outdated and dedicated.
First of all, WPF uses MVVM pattern that you should try to follow, but except that you can use the HttpClient in using System.Net.Http;.
To download multiple files in a parallel you can create a parallel foreach that handles all the downloads that the HttpClient have to perform. You did tis right but the foreach will block the thread so start it in a new one Task.Run(()=>{// Your Code});
In the case you don’t want do write something like that yourself, you could use the Shard Download Library on NuGet. This NuGet Package is also on GitHub if you want to see how it does its job. It helped me often if I want do download a lot of files, because is does not block the UI thread and is easy to use. To use it you have to write something like this:
void Download()
{
string[] links = new string[]{
"https://google.com",
"https://speed.hetzner.de/100MB.bin",
"https://file-examples.com/storage/fe88dacf086398d1c98749c/2017/04/file_example_MP4_1920_18MG.mp4" };
foreach (var link in links)
{
_ = new LoadRequest(link);
}
Console.ReadLine();
}
But you can also set the MaxDegreeOfParalism and you can change it while it is downloading. You can set the Path for the output file and name it. The problem that the HttpClient has with download finished and progress report is also solved with this. The bad thing is that the documentation of this library is not very good. Here an example with few options as an example.
async Task DownloadAsync()
{
string[] links = new string[]{
"https://google.com",
"https://speed.hetzner.de/100MB.bin",
"https://file-examples.com/storage/fe88dacf086398d1c98749c/2017/04/file_example_MP4_1920_18MG.mp4" };
RequestHandler requestHandler = new()
{
MaxDegreeOfParallelism = 10
};
LoadRequestOptions option = new()
{
Progress = new Progress<float>(value => Console.WriteLine(value.ToString("0.0%"))),
DestinationPath = "C:\\Users\\[UserName]\\Desktop\\",
RequestCompleated = path => Console.WriteLine("Finished: " + path?.ToString()),
RequestHandler = requestHandler
};
LoadRequest last = null;
foreach (string link in links)
{
last = new LoadRequest(link, option);
}
await last.Task;
}
I hope that can help people that have the same problem and don’t want to use the dedicated WebClient.

Upload large files 100mb+ to Sharepoint 2010 via c# Web Service

I am unable to upload large files to Sharepoint 2010. I am using Visual Studio 2010 and Language C#. I have tried multiple ways from content I have found online but nothing has worked. I have changed the settings and config files to the maximum allowed upload limits and still nothing. I am using the copy.asmx for small files which works fine and am trying UploadDataAsync when the file is too large and an exception is thrown but this is not working. Please take a look at the code below...
Any/all assistance is greatly appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace ListsService
{
public class UploadDocumentcs
{
public string UploadResult { get; set; }
public string Errors { get; set; }
public UploadDataCompletedEventHandler WebClient_UploadDataCompleted { get; set; }
public byte[] content { get; set; }
public void UploadDocumentToSP(string localFile, string remoteFile)
{
string result = string.Empty;
SPCopyService.CopySoapClient client = new SPCopyService.CopySoapClient();
string sUser = "user";
string sPwd = "pwd";
string sDomain = "dmn";
System.Net.NetworkCredential NC = new System.Net.NetworkCredential(sUser, sPwd, sDomain);
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
client.ClientCredentials.Windows.ClientCredential = NC;
try
{
client.Open();
string url = "http://SP/TestLibrary/";
string fileName = localFile.Substring(localFile.LastIndexOf('\\'), (localFile.Length - localFile.LastIndexOf('\\')));
fileName = fileName.Remove(0, 1);
string[] destinationUrl = { url + fileName };
System.IO.FileStream fileStream = new System.IO.FileStream(localFile, System.IO.FileMode.Open);
byte[] content = new byte[(int)fileStream.Length];
fileStream.Read(content, 0, (int)fileStream.Length);
fileStream.Close();
// Description Information Field
SPCopyService.FieldInformation descInfo = new SPCopyService.FieldInformation
{
DisplayName = "Description",
Type = SPCopyService.FieldType.File,
Value = "Test file for upload"
};
SPCopyService.FieldInformation[] fileInfoArray = { descInfo };
SPCopyService.CopyResult[] arrayOfResults;
uint result2 = client.CopyIntoItems(fileName, destinationUrl, fileInfoArray, content, out arrayOfResults);
// Check for Errors
foreach (SPCopyService.CopyResult copyResult in arrayOfResults)
{
string msg = "====================================" +
"SharePoint Error:" +
"\nUrl: " + copyResult.DestinationUrl +
"\nError Code: " + copyResult.ErrorCode +
"\nMessage: " + copyResult.ErrorMessage +
"====================================";
Errors = string.Format("{0};{1}", Errors, msg);
}
UploadResult = "File uploaded successfully";
}
catch (OutOfMemoryException)
{
System.Uri uri = new Uri("http://bis-dev-srv2:300/DNATestLibrary/");
(new System.Net.WebClient()).UploadDataCompleted += new UploadDataCompletedEventHandler(WebClient_UploadDataCompleted);
(new System.Net.WebClient()).UploadDataAsync(uri, content);
}
finally
{
if (client.State == System.ServiceModel.CommunicationState.Faulted)
{
client.Abort();
UploadResult = "Upload aborted due to error";
}
if (client.State != System.ServiceModel.CommunicationState.Closed)
{
client.Close();
}
}
}
void WcUpload_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
{
if (e != null)
{
UploadResult = "Upload Unuccessful";
}
else
{
UploadResult = "Upload Successful";
//throw new NotImplementedException();
}
}
}
}
Shaun
In order to get this to work, you will have to make changes to the SharePoint configuration to increase the upload limit and the time out. The link below shows the necessary steps to get large file uploads to work.
http://blogs.technet.com/b/sharepointcomic/archive/2010/02/14/sharepoint-large-file-upload-configuration.aspx
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
namespace UploadTester
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void btnSelectFile_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
textBox1.Text = openFileDialog1.FileName;
}
private void btnUpload_Click(object sender, EventArgs e)
{
try
{
byte[] content = GetByteArray();
string filename = Path.GetFileName(openFileDialog1.FileName);
System.Net.WebClient webClient = new System.Net.WebClient();
System.Uri uri = new Uri("http://SP/DNATestLibrary/" + filename);
webClient.Credentials = new NetworkCredential("username", "pwd", "domain");
webClient.UploadData(uri, "PUT", content);
MessageBox.Show("Upload Successful");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
byte[] GetByteArray()
{
FileStream fileStream = new System.IO.FileStream(openFileDialog1.FileName, System.IO.FileMode.Open);
byte[] content = new byte[(int)fileStream.Length];
fileStream.Read(content, 0, (int)fileStream.Length);
fileStream.Close();
return content;
}
private void btnUploadAsync_Click(object sender, EventArgs e)
{
try
{
byte[] content = GetByteArray();
string filename = Path.GetFileName(openFileDialog1.FileName);
System.Net.WebClient webClient = new System.Net.WebClient();
System.Uri uri = new Uri("http://SP/DNATestLibrary/" + filename);
webClient.UploadDataCompleted += new UploadDataCompletedEventHandler(webClient_UploadDataCompleted);
webClient.Credentials = new NetworkCredential("username", "pwd", "domain");
webClient.UploadDataAsync(uri, "PUT", content);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
void webClient_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
{
if (e.Error == null)
{
MessageBox.Show("Upload Successful");
}
else
{
MessageBox.Show(e.ToString());
}
}
}
}

Categories