C# Auto Update Program - c#

OK, I am working on a program that will automatically download an update if the versions don't match.
The problem now is that it loads the info from an XML file, but it doesn't download the files specified.
Any suggestions to improve the code are welcome as well!
Here is the complete source code:
http://www.mediafire.com/?44d9mcuhde9fv3e
http://www.virustotal.com/file-scan/report.html?id=178ab584fd87fd84b6fd77f872d9fd08795f5e3957aa8fe7eee03e1fa9440e74-1309401561
Thanks in advance for the help!
EDIT
The File to download, specified in Program.cs does not download and the program gets stuck at
currentFile = string.Empty;
label1.Text = "Preparing to download file(s)...";
Thread t = new Thread(new ThreadStart(DownloadFiles)); // Making a new thread because I prefer downloading 1 file at a time
t.Start();
and it start the "Thread t".
Code that seems to be making problems:
UpdateForm.cs
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.NetworkInformation;
using System.Net;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.InteropServices;
namespace LauncherBeta1
{
public partial class UpdateForm : Form
{
const int MF_BYPOSITION = 0x400;
[DllImport("User32")]
private static extern int RemoveMenu(IntPtr hMenu, int nPosition, int wFlags);
[DllImport("User32")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("User32")]
private static extern int GetMenuItemCount(IntPtr hWnd);
private static WebClient webClient = new WebClient();
internal static List<Uri> uriFiles = new List<Uri>();
internal static Uri uriChangelog = null;
private static long fileSize = 0, fileBytesDownloaded = 0;
private static Stopwatch fileDownloadElapsed = new Stopwatch();
bool updateComplete = false, fileComplete = false;
string currentFile = string.Empty, labelText = string.Empty;
int progbarValue = 0, KBps = 0;
public UpdateForm()
{
IntPtr hMenu = GetSystemMenu(this.Handle, false);
int menuItemCount = GetMenuItemCount(hMenu);
RemoveMenu(hMenu, menuItemCount - 1, MF_BYPOSITION);
InitializeComponent();
XmlDocument xdoc = new XmlDocument();
xdoc.Load("http://raiderz.daregamer.com/updates/app_version.xml");
XmlNode xNodeVer = xdoc.DocumentElement.SelectSingleNode("Version");
FileVersionInfo fileVer = FileVersionInfo.GetVersionInfo(AppDomain.CurrentDomain.BaseDirectory + "lua5.1.dll");
int ver_app = Convert.ToInt32(fileVer.FileVersion.ToString());
int ver_xml = Convert.ToInt32(xNodeVer);
if (ver_xml == ver_app)
{
Application.Run(new Form1());
Environment.Exit(0);
}
else
{
if (ver_xml < ver_app || ver_xml > ver_app)
{
if (uriChangelog != null)
{
label1.Text = "Status: Downloading changelog...";
try
{
string log = webClient.DownloadString(uriChangelog);
log = log.Replace("\n", Environment.NewLine);
txtboxChangelog.Text = log;
}
catch (WebException ex) { }
}
foreach (Uri uri in uriFiles)
{
string uriPath = uri.OriginalString;
currentFile = uriPath.Substring(uriPath.LastIndexOf('/') + 1);
if (File.Exists(currentFile))
{
label1.Text = "Status: Deleting " + currentFile;
File.Delete(currentFile);
}
}
currentFile = string.Empty;
label1.Text = "Preparing to download file(s)...";
Thread t = new Thread(new ThreadStart(DownloadFiles)); // Making a new thread because I prefer downloading 1 file at a time
t.Start();
}
else
{
//MessageBox.Show("Client is up to date!");
Application.Run(new Form1());
Environment.Exit(0);
}
}
}
private void DownloadFiles()
{
foreach (Uri uri in uriFiles)
{
try
{
fileComplete = false;
fileDownloadElapsed.Reset();
fileDownloadElapsed.Start();
string uriPath = uri.OriginalString;
currentFile = uriPath.Substring(uriPath.LastIndexOf('/') + 1);
webClient.DownloadFileAsync(uri, currentFile);
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged);
while (!fileComplete) { Thread.Sleep(1000); }
}
catch { continue; }
}
currentFile = string.Empty;
updateComplete = true;
}
void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progbarValue = e.ProgressPercentage;
fileSize = e.TotalBytesToReceive / 1024;
fileBytesDownloaded = e.BytesReceived / 1024;
if (fileBytesDownloaded > 0 && fileDownloadElapsed.ElapsedMilliseconds > 1000)
{
KBps = (int)(fileBytesDownloaded / (fileDownloadElapsed.ElapsedMilliseconds / 1000));
}
labelText = "Status: Downloading " + currentFile +
"\n" + fileBytesDownloaded + " KB / " + fileSize + " KB - " + KBps + " KB/s";
}
void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
progbarValue = 0;
fileComplete = true;
}
/// <summary>
/// Returns file size (Kb) of a Uri
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
private long GetFileSize(Uri uri)
{
try
{
WebRequest webRequest = HttpWebRequest.Create(uri);
using (WebResponse response = webRequest.GetResponse())
{
long size = response.ContentLength;
return size / 1024;
}
}
catch { return 1; }
}
private void timerMultiPurpose_Tick(object sender, EventArgs e)
{
if (updateComplete == true)
{
updateComplete = false;
label1.Text = "Status: Complete";
progressBar1.Value = 0;
MessageBox.Show("Update complete!!");
Application.Run(new Form1());
Environment.Exit(0);
}
else
{
progressBar1.Value = progbarValue;
label1.Text = labelText;
}
}
private void UI_FormClosing(object sender, FormClosingEventArgs e)
{
Environment.Exit(0);
}
}
}
Relevant code from Program.cs:
System.Threading.Thread.Sleep(1000); // Give the calling application time to exit
XmlDocument xdoc = new XmlDocument();
xdoc.Load("http://raiderz.daregamer.com/updates/app_version.xml");
XmlNode xNodeVer = xdoc.DocumentElement.SelectSingleNode("Loc");
string ver_xml = Convert.ToString(xNodeVer);
args = new string[2];
args[0] = "Changelog=http://raiderz.daregamer.com/updates/changelog.txt";
args[1] = "URIs=" + ver_xml;
if (args.Length == 0)
{
MessageBox.Show("Can not run program without parameters", "Error");
return;
}
try
{
foreach (string arg in args)
{
if (arg.StartsWith("URIs="))
{
string[] uris = arg.Substring(arg.IndexOf('=') + 1).Split(';');
foreach (string uri in uris)
{
if (uri.Length > 0)
{
UpdateForm.uriFiles.Add(new Uri(uri));
}
}
}
else if (arg.StartsWith("Changelog="))
{
UpdateForm.uriChangelog = new Uri(arg.Substring(arg.IndexOf('=') + 1));
}
}
}
catch { MessageBox.Show("Missing or faulty parameter(s)", "Error"); }

I've not downloaded or reviewed your code, but if this is all C# based and on the v2.0 framework or higher you may want to check in to using ClickOnce. It will handle much of the auto updating for you and even allow users to continue using the program if they are offline and unable to connect to your update server.

Related

Application inexplicably failing capturing screenshots

I have an odd issue that I have been trying to pin down for awhile. Essentially my application opens up various URL's using chrome (data from an array), takes a picture of them, saves them, and continues on looping through the array. The application successfully launches and runs, but variably it fails (usually between 2-5 days). When it fails, chrome no longer appears to open but the application continues to 'run'. Here is the error that is being produced from my try/catches:
at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation)
at Command_Center_Screen_Capture_Agent.Form1.Capture(String name)
My only working theory right now is that there might be an issue with the memory since it's failing to take the picture and failing to open the browser, but I'm not sure how to test that theory.
{UPDATE} Going through the logs on all of my servers, I noticed that while only some had the error above, all of them had the following error:
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at Command_Center_Screen_Capture_Agent.Form1.Capture(String name) in SERVER REDACTED\Visual Studio 2012\Projects\Command Center Screen Capture Agent\Command Center Screen Capture Agent\Form1.cs:line 170
This error appears to always be the last error before the system stopped logging and (theoretically) failed.
The code in question is:
try
{
GFX.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
}
catch (Exception e)
{
//Noticed without this if the program was running before skyvision was opened an occasional error popped up
error_logging(e.StackTrace);
}
// Save the screenshot to the specified path
try
{
String filePath = #"\" + pictureNames[count] + ".png";
// MessageBox.Show("Saving file to: " + FILEPATH_LOCATION + forTesting);
BIT.Save(#FILEPATH_LOCATION + #filePath, ImageFormat.Png);
System.Threading.Thread.Sleep(2000);
count++;
_capture.Enabled = true;
}
catch (Exception e)
{
error_logging(e.StackTrace);
//Save error without breaking in case issue with path
//MessageBox.Show("CAPTURE ERROR: \n\n" + e.StackTrace);
}
The full source 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.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.IO;
using System.Configuration;
namespace Command_Center_Screen_Capture_Agent
{
public partial class Form1 : MaterialSkin.Controls.MaterialForm
{
public Form1()
{
InitializeComponent();
}
//Array storage for URLs and pic names
public static String[] URLS;
public static String[] pictureNames; //Used to save picture by name
//Data
static List<String> URL_LIST = new List<String>();
static List<String> URL_DESC = new List<String>();
static String base_url_1 = "URL_OMITTED";
static String base_url_2 = "URL_OMITTED";
static Configuration configManager = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
int count = 0;
//Create a new bitmap.
static Image BIT = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
Graphics GFX = Graphics.FromImage(BIT);
string FILEPATH_LOCATION = (#"FILEPATH_OMITTED");
string ERROR_LOGGING = Path.Combine(Application.StartupPath, "Error Logs");
private void error_logging(string line)
{
try
{
Guid filename = Guid.NewGuid();
string targetPath = Path.Combine(ERROR_LOGGING, filename + ".txt");
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(targetPath))
{
file.WriteLine(line);
}
}
catch (Exception E)
{
MessageBox.Show("Failure Writing Error log. " + E.StackTrace);
}
}
private void load_data()
{
//Attempt to load data
try
{
string line;
System.IO.StreamReader file =
new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + "data.txt");
while ((line = file.ReadLine()) != null)
{
if (line.Contains("SERVERS:"))
{
URL_LIST = line.Substring(8).Split(',').ToList();
}
if (line.Contains("DESC:"))
{
URL_DESC = line.Substring(5).Split(',').ToList();
}
}
file.Close();
}
catch (Exception criticalError)
{
MessageBox.Show("Critical Error. Could not access data file. Closing application. \n\n" + criticalError.StackTrace);
Application.Exit();
}
}
private void build_error_log()
{
if (!Directory.Exists(ERROR_LOGGING))
{
Directory.CreateDirectory(ERROR_LOGGING);
}
}
private void Form1_Load(object sender, EventArgs e)
{
build_error_log();
load_data();
Checkpath();
cycleTimeTxtBx.Text = Properties.Settings.Default.TimeToLoadPage.ToString();
}
private bool Checkpath()
{
this.Hide();
if (Directory.Exists(FILEPATH_LOCATION))
{
return (true);
}
else
{
DirectoryInfo dir = Directory.CreateDirectory(FILEPATH_LOCATION);
return false;
}
}
private void Capture(string name)
{
try
{
if (!Checkpath())
{
System.Threading.Thread.Sleep(1000);
}
}
catch (Exception whoops)
{
error_logging(whoops.StackTrace);
//Console.WriteLine(whoops);
}
// Take the screenshot from the upper left corner to the right bottom corner.
try
{
GFX.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
}
catch (Exception e)
{
error_logging(e.StackTrace);
}
// Save the screenshot to the specified path
try
{
String filePath = #"\" + pictureNames[count] + ".png";
BIT.Save(#FILEPATH_LOCATION + #filePath, ImageFormat.Png);
System.Threading.Thread.Sleep(2000);
count++;
_capture.Enabled = true;
}
catch (Exception e)
{
error_logging(e.StackTrace);
//Save error without breaking in case issue with path
//MessageBox.Show("CAPTURE ERROR: \n\n" + e.StackTrace);
}
KillChrome();
}
private void KillChrome()
{
try
{
Process[] procsChrome = Process.GetProcessesByName("chrome");
foreach (Process pro in procsChrome)
{
pro.Kill();
}
}
catch (Exception e)
{
error_logging(e.StackTrace);
Console.WriteLine(e);
}
}
private void _capture_Tick(object sender, EventArgs e)
{
//Assume that the URL array hasn't been setup
if (URLS == null || URLS.Length < 1)
{
URLS = URL_LIST.ToArray();
pictureNames = URL_DESC.ToArray();
}
try
{
Process process = new Process();
process.StartInfo.FileName = "chrome.exe";
if (count < URLS.Length)
{
string sysCode = URLS[count];
string market;
int delimIndex = sysCode.IndexOf("|");
market = sysCode.Substring(delimIndex + 1);
sysCode = sysCode.Substring(0, delimIndex);
string useable_url = base_url_1 + sysCode + base_url_2 + market;
process.StartInfo.Arguments = useable_url + " --start-maximized --incognito --new-window";
}
else
{
count = 0;
string sysCode = URLS[count];
string market;
int delimIndex = sysCode.IndexOf("|");
market = sysCode.Substring(delimIndex + 1);
sysCode = sysCode.Substring(0, delimIndex);
string useable_url = base_url_1 + sysCode + base_url_2 + market;
process.StartInfo.Arguments = useable_url + " --start-maximized --incognito --new-window";
}
process.Start();
_capture.Enabled = false;
System.Threading.Thread.Sleep(Properties.Settings.Default.TimeToLoadPage * 1000);
Capture("no");
}
catch (Exception error)
{
error_logging(error.StackTrace);
//MessageBox.Show(error.StackTrace);
}
}
private void startBTN_Click(object sender, EventArgs e)
{
_capture.Enabled = true;
this.Hide();
notifyIcon1.Visible = true;
}
private void saveBtn_Click(object sender, EventArgs e)
{
try
{
Properties.Settings.Default.TimeToLoadPage = Convert.ToInt32(cycleTimeTxtBx.Text);
Properties.Settings.Default.Save();
}
catch (Exception error)
{
MessageBox.Show("Error: Unable to parse cycle timer. Please only use integers when setting the cycle time.", "Parsing Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
cycleTimeTxtBx.Text = Properties.Settings.Default.TimeToLoadPage.ToString();
}
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Console.WriteLine("Clicked");
Show();
_capture.Enabled = false;
this.WindowState = FormWindowState.Normal;
notifyIcon1.Visible = false;
}
}
}

Why when uploading a video file to youtube it's uploading it to my second gmail account?

On my desktop pc i have one gmail account.
On my laptop here i have another differenet gmail account.
My JSON file: client_secrets contain on both laptop and desktop pc same one gmail account the one on my desktop pc. But when i'm uploading the video file from my laptop it's uploading it to my gmail account on the laptop. And i want it to upload it to my gmail youtube account on my desktop pc.
First why on the laptopn it's uploading to the gmail account on the laptop and not the gmail on the desktop pc ?
Second how can i change it ? Even if on laptop and desktop pc i'm using same client_secrets file on laptopn it's uploading it to the gmail on the laptop.
another thing is that on my laptop i'm connected to my gmail account of the laptop and on the desktop pc connected to the gmail account of the desktop pc.
But i was sure that the gmail account on the JSON file set where the file will be upload to.
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 Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Google.GData.Client;
using Google.GData.Extensions;
using System.Reflection;
using System.IO;
using System.Threading;
using System.Net;
namespace Youtubeupload
{
public partial class Youtube_Uploader : Form
{
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Text;
}
}
YouTubeService service;
string apiKey = "myapikey";
string FileNameToUpload = "";
string[] stringProgressReport = new string[5];
long totalBytes = 0;
DateTime dt;
public static string fileuploadedsuccess = "";
Upload upload;
public Youtube_Uploader(string filetoupload)
{
InitializeComponent();
FileNameToUpload = #"C:\Users\tester\Videos\test.mp4";
service = AuthenticateOauth(apiKey);
var videoCatagories = service.VideoCategories.List("snippet");
videoCatagories.RegionCode = "IL";
var result = videoCatagories.Execute();
MakeRequest();
backgroundWorker1.RunWorkerAsync();
}
public static string uploadstatus = "";
Video objects = null;
private void videosInsertRequest_ResponseReceived(Video obj)
{
System.Timers.Timer aTimer;
aTimer = new System.Timers.Timer();
aTimer.Elapsed += aTimer_Elapsed;
aTimer.Interval = 10000;
aTimer.Enabled = false;
uploadstatus = obj.Status.UploadStatus;
if (uploadstatus == "uploaded")
{
fileuploadedsuccess = "file uploaded successfully";
}
if (uploadstatus == "Completed")
{
fileuploadedsuccess = "completed";
}
objects = obj;
}
void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
}
double mbSent = 0;
int percentComplete = 0;
VideoProcessingDetailsProcessingProgress vp = new VideoProcessingDetailsProcessingProgress();
private void videosInsertRequest_ProgressChanged(IUploadProgress obj)
{
ulong? ul = vp.TimeLeftMs;
stringProgressReport[1] = obj.Status.ToString();
mbSent = ((double)obj.BytesSent) / (1 << 20);
stringProgressReport[2] = mbSent.ToString();
percentComplete = (int)Math.Round(((double)obj.BytesSent) / totalBytes * 100);
stringProgressReport[3] = percentComplete.ToString();
if (obj.BytesSent != 0)
{
var currentTime = DateTime.Now;
TimeSpan diff = currentTime - dt;
double diffSeconds = (DateTime.Now - dt).TotalSeconds;
double averageSpeed = obj.BytesSent / diffSeconds;
double MBunits = ConvertBytesToMegabytes((long)averageSpeed);
stringProgressReport[4] = string.Format("{0:f2} MB/s", MBunits);
}
}
public static YouTubeService AuthenticateOauth(string apiKey)
{
try
{
YouTubeService service = new YouTubeService(new YouTubeService.Initializer()
{
ApiKey = apiKey,
ApplicationName = "YouTube Uploader",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return null;
}
}
private void MakeRequest()
{
var searchListRequest = service.Search.List("snippet");
searchListRequest.Q = "daniel lipman gta"; // Replace with your search term.
searchListRequest.RegionCode = "IL";
searchListRequest.MaxResults = 50;
// Call the search.list method to retrieve results matching the specified query term.
var searchListResponse = searchListRequest.Execute();
List<string> videos = new List<string>();
List<string> channels = new List<string>();
List<string> playlists = new List<string>();
// matching videos, channels, and playlists.
foreach (var searchResult in searchListResponse.Items)
{
switch (searchResult.Id.Kind)
{
case "youtube#video":
videos.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.VideoId));
break;
case "youtube#channel":
channels.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.ChannelId));
break;
case "youtube#playlist":
playlists.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.PlaylistId));
break;
}
}
}
static Video video = new Video();
private void UploadVideo(string FileName, string VideoTitle, string VideoDescription)
{
try
{
UserCredential credential;
using (FileStream stream = new FileStream(#"D:\C-Sharp\Youtube-Manager\Youtube-Manager\Youtube-Manager\bin\Debug\client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.Youtube, YouTubeService.Scope.YoutubeUpload },
"user",
CancellationToken.None,
new FileDataStore("YouTube.Auth.Store")).Result;
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
});
video.Snippet = new VideoSnippet();
video.Snippet.Title = VideoTitle;
video.Snippet.Description = VideoDescription;
video.Snippet.Tags = new string[] { "tag1", "tag2" };
video.Status = new VideoStatus();
video.Status.PrivacyStatus = "public";
using (var fileStream = new FileStream(FileName, FileMode.Open))
{
const int KB = 0x400;
var minimumChunkSize = 256 * KB;
var videosInsertRequest = youtubeService.Videos.Insert(video,
"snippet,status", fileStream, "video/*");
videosInsertRequest.ProgressChanged +=
videosInsertRequest_ProgressChanged;
videosInsertRequest.ResponseReceived +=
videosInsertRequest_ResponseReceived;
// The default chunk size is 10MB, here will use 1MB.
videosInsertRequest.ChunkSize = minimumChunkSize * 3;
dt = DateTime.Now;
videosInsertRequest.Upload();
}
}
catch (Exception errors)
{
string errorss = errors.ToString();
}
}
static double ConvertBytesToMegabytes(long bytes)
{
return (bytes / 1024f) / 1024f;
}
private void Youtube_Uploader_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
UploadVideo(FileNameToUpload, "Gta v ps4", "Testing gta v ps4");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int eventIndex = 0;
try
{
eventIndex = (int)e.UserState;
}
catch
{
MessageBox.Show(e.UserState == null ? "null" : e.UserState.GetType().FullName);
throw;
}
if (eventIndex == 0) // upload status.
{
label14.Text = stringProgressReport[0];
}
else if (eventIndex == 1) // obj.Status
{
label16.Text = stringProgressReport[1];
}
else if (eventIndex == 2) // mb sent so far
{
stringProgressReport[2];
label5.Text = stringProgressReport[2];
}
else if (eventIndex == 3) // percent complete
{
progressBar1.Value = Int32.Parse(stringProgressReport[3]);
}
else if (eventIndex == 4) // percent complete
{
label8.Text = stringProgressReport[4];
}
else
{
throw new Exception("Invalid event index: " + eventIndex);
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
}
}
}
What i want is that it will upload the video files to my gmail account that is on the desktop pc even if i'm uploading it from the laptop pc and there i'm connected to another gmail account.

My C# multi-threaded console application seems to not be multithreaded

Here's my C# console program that uses Powerpoint to convert ppt files to folders of pngs. This is supposed to be an automated process that runs on its own server.
I expect that as soon as a thread creates an image from a file, it should immediately remove the images and the source file.
The actual behavior is that, if five threads are running, it'll wait for five folders of images to be created before any thread can move any files. I'm able to see the images being created, and compare that with the Console readout, so I can see that a thread isn't trying to move the file.
Only after all the other threads have made their images, will any thread try to move the files. I suspect this is wrong.
This is an Amazon EC2 Medium instance, and it appears to max out the CPU, so five threads might be too much for this.
I also find that I can hardly use Windows Explorer while this program is running.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using Microsoft.Office.Core;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using System.Diagnostics;
using System.Timers;
namespace converter
{
class Program
{
public static int threadLimit=0;
public static int currThreads = 0;
static void Main(string[] args)
{
var inDir = args[0];
var outDir = args[1]+"\\";
var procDir = args[2]+"\\";
Int32.TryParse(args[3],out threadLimit);
Thread[] converterThreads = new Thread[threadLimit];
while (true)
{
System.Threading.Thread.Sleep(1000);
var filePaths = Directory.GetFiles(inDir, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".pptx") && !s.Contains("~$") || s.EndsWith(".ppt") && !s.Contains("~$"));
var arrPaths = filePaths.ToArray();
for(var i=0; i< arrPaths.Length; i++)
{
if (currThreads < threadLimit && currThreads < arrPaths.Length)
{
Console.WriteLine("currThreads= " + currThreads + " paths found= " + arrPaths.Length);
try
{
var fileNameWithoutExtension = arrPaths[currThreads].Replace(inDir, "").Replace(".pptx", "").Replace(".ppt", "").Replace("\\", "");
var filenameWithExtension = arrPaths[currThreads].Substring(arrPaths[currThreads].LastIndexOf("\\") + 1);
var dir = arrPaths[currThreads].Replace(".pptx", "").Replace(".ppt", "");
Conversion con = new Conversion(arrPaths[currThreads], dir, outDir, procDir, filenameWithExtension, fileNameWithoutExtension);
converterThreads[i] = new Thread(new ThreadStart(con.convertPpt));
converterThreads[i].Start();
Console.WriteLine(converterThreads[i].ManagedThreadId + " is converting " + fileNameWithoutExtension);
}
catch (Exception e)
{
Console.WriteLine(string.Format("Unable to convert {0} ", arrPaths[i]) + e);
}
}
}
for (var i = 0; i < converterThreads.Length; i++)
{
if (converterThreads[i] != null)
{
if (!converterThreads[i].IsAlive)
{
converterThreads[i].Abort();
converterThreads[i].Join(1);
Console.WriteLine("thread " + converterThreads[i].ManagedThreadId + " finished, "+currThreads+" remaining");
converterThreads[i] = null;
}
}
}
if (currThreads == 0)
{
try
{
foreach (Process proc in Process.GetProcessesByName("POWERPNT"))
{
proc.Kill();
}
}
catch (Exception e3)
{
}
}
}
}
}
class Logger{
static void toLog(String msg)
{
//TODO: log file
}
}
class Conversion{
static int numberOfThreads=0;
String input;
String output;
String outDir;
String process;
String nameWith;
String nameWithout;
int elapsedTime;
System.Timers.Timer time;
public Conversion(String input, String output, String outDir, String processDir, String nameWith, String nameWithout)
{
this.input = input;
this.output = output;
this.outDir = outDir;
process = processDir;
this.nameWith = nameWith;
this.nameWithout = nameWithout;
numberOfThreads++;
Console.WriteLine("number of threads running: " + numberOfThreads);
Program.currThreads = numberOfThreads;
time = new System.Timers.Timer(1000);
time.Start();
time.Elapsed += new ElapsedEventHandler(OnTimedEvent);
elapsedTime = 0;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
elapsedTime++;
}
public void convertPpt()
{
var app = new PowerPoint.Application();
var pres = app.Presentations;
try
{
var file = pres.Open(input, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
file.SaveAs(output, Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPNG, MsoTriState.msoTrue);
file.Close();
app.Quit();
Console.WriteLine("file converted " + input);
}
catch (Exception e)
{
Console.WriteLine("convertPpt failed");
}
moveFile();
moveDir();
}
public void moveFile()
{
Console.WriteLine("moving" + input);
try
{
System.Threading.Thread.Sleep(500);
Console.WriteLine(string.Format("moving {0} to {1}", input, process + nameWith));
if (File.Exists(process + nameWith))
{
File.Replace(input, process + nameWith, null);
}
else
{
File.Move(input, process + nameWith);
}
}
catch (Exception e)
{
Console.WriteLine(string.Format("Unable to move the file {0} ", input) + e);
try
{
foreach (Process proc in Process.GetProcessesByName("POWERPNT"))
{
proc.Kill();
}
}
catch (Exception e3)
{
}
}
}
public void moveDir()
{
Console.WriteLine("moving dir " + output);
try
{
System.Threading.Thread.Sleep(500);
Console.WriteLine(string.Format("moving dir {0} to {1} ", output, outDir + nameWithout));
if (Directory.Exists(outDir + nameWithout))
{
Directory.Delete(outDir + nameWithout, true);
}
if (Directory.Exists(output))
{
Directory.Move(output, outDir + nameWithout);
}
}
catch (Exception e)
{
Console.WriteLine(string.Format("Unable to move the directory {0} ", output) + e);
try
{
foreach (Process proc in Process.GetProcessesByName("POWERPNT"))
{
proc.Kill();
}
}
catch (Exception e3)
{
}
}
finally
{
numberOfThreads--;
Program.currThreads = numberOfThreads;
Console.WriteLine("took " + elapsedTime + "seconds");
}
}
}
}
Every 1000ms you get a list of files in inDir and potentially start a thread to process each file. You have very complex logic surrounding whether or not to start a new thread, and how to manage the lifetime of the thread.
The logic is too complex for me to spot the error without debugging the code. However, I would propose an alternative.
Have a single thread watch for new files and place the file path into a BlockingCollection of files for processing. That thread does nothing else.
Have N additional threads that retrieve file paths from the BlockingCollection and process them.
This is known as a Producer / Consumer pattern and is ideal for what you are doing.
The example code at the bottom of the linked MSDN page shows an implementation example.
On a side note, you are catching and swallowing Exception e3. Don't catch something you will not handle, it hides problems.

The notorious yet unaswered issue of downloading a file when windows security is required

There is a web site: http://site.domain.com which prompts for credentials with "windows security" dialog box. So I managed to use WebBrowser control to navigate to the page and send keystrokes to enter the password - I could not find another way around.
Now I came to the point where the website generates a link to a file I want to download, it looks like: http://site.domain.com/operations/reporting/csv/Report720_2553217.csv
I tried to use WebClient to download the file but it does nothing (br is my WebBrowser control):
WebClient wb = new WebClient();
wb.Headers.Add( br.Document.Cookie);
wb.DownloadFile(link, #"report.csv");
I have been trying to find a working solution to no avail. I know the web client is not authenticated so tried to use web browser's cookie but it does not work. The cookie looks as follows:
TLTUID=61FE48D8F9B910F9E930F42D6A03EAA6; TLTSID=0B2B8EE82688102641B7E768807FA8B2; s_cc=true; s_sq=%5B%5BB%5D%5D; ASPSESSIONIDQQSTRDQS=FNPJCODCEMGFIDHFLKDBEMHO
So I have two questions:
How to allow web client to download a file accessible from web browser's session. What am I doing wrong in the above code sample?
Is there an easy way to use WebBrowser solely to download and save that file to the path and filename of my choice? Or how to do it all using WebClient or something else?
Not possible, AFAIK. WebClient and WebBrowser use different layers to access web. WebClient uses WinHTTP, WebBrowser uses UrlMon. Thus, they would have separate sessions (including the authentication cache).
That's possible, just use any of UrlMon APIs to download the file, e.g. URLDownloadToFile or URLDownloadToCacheFile. I've just answered a similar question.
On a side note, you don't have to feed in keystrokes to provide authentication credentials. You can implement IAuthenticateEx on WebBrowser site object for this. Here is more info.
So this is the working solution which meets the requirements given in my question. It automatically navigates to the specified website, authenticates and downloads a generated report. I used this Q/A as an outline.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;
using System.Web;
using System.Security.Authentication;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Win32;
using System.Runtime.CompilerServices;
using System.Security.Policy;
namespace margot_report
{
[ComImport,
Guid("00000112-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleObject
{
void SetClientSite(IOleClientSite pClientSite);
}
[ComImport,
Guid("00000118-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleClientSite
{
void SaveObject();
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void GetContainer(object ppContainer);
void ShowObject();
void OnShowWindow(bool fShow);
void RequestNewObjectLayout();
}
[ComImport,
GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr
ppvObject);
}
[ComImport]
[Guid("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAuthenticate
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Authenticate(IntPtr phwnd,
[MarshalAs(UnmanagedType.LPWStr)] ref string pszUsername,
[MarshalAs(UnmanagedType.LPWStr)] ref string pszPassword);
}
class SelfAuthenticatingWebBrowser : WebBrowser, IOleClientSite, IAuthenticate, IServiceProvider
{
public static Guid IID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
public static Guid SID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
public const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
public const int S_OK = unchecked((int)0x00000000);
public void Authenticate(IntPtr phwnd, ref string pszUsername, ref string pszPassword)
{
Console.WriteLine("Authenticate");
pszUsername = Program.username; //
pszPassword = Program.password; //
//return S_OK;
}
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
{
//Console.WriteLine("QueryService");
int nRet = guidService.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal
if (nRet == 0)
{
nRet = riid.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal
if (nRet == 0)
{
ppvObject = Marshal.GetComInterfaceForObject(this,
typeof(IAuthenticate));
return S_OK;
}
}
ppvObject = new IntPtr();
return INET_E_DEFAULT_ACTION;
}
public void SaveObject()
{
throw new NotImplementedException();
}
public void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk)
{
throw new NotImplementedException();
}
public void GetContainer(object ppContainer)
{
throw new NotImplementedException();
}
public void ShowObject()
{
throw new NotImplementedException();
}
public void OnShowWindow(bool fShow)
{
throw new NotImplementedException();
}
public void RequestNewObjectLayout()
{
throw new NotImplementedException();
}
public IComponent Component
{
get { throw new NotImplementedException(); }
}
public IContainer Container
{
get { throw new NotImplementedException(); }
}
public bool DesignMode
{
get { throw new NotImplementedException(); }
}
public string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
class Program
{
static bool send = true, verbose=false, clicked=false, submitted=false;
static int c = 0, t=0;
public static string filename, report, username, password;
/// <summary>
/// The URLMON library contains this function, URLDownloadToFile, which is a way
/// to download files without user prompts. The ExecWB( _SAVEAS ) function always
/// prompts the user, even if _DONTPROMPTUSER parameter is specified, for "internet
/// security reasons". This function gets around those reasons.
/// </summary>
/// <param name="pCaller">Pointer to caller object (AX).</param>
/// <param name="szURL">String of the URL.</param>
/// <param name="szFileName">String of the destination filename/path.</param>
/// <param name="dwReserved">[reserved].</param>
/// <param name="lpfnCB">A callback function to monitor progress or abort.</param>
/// <returns>0 for okay.</returns>
[DllImport("URLMON.DLL", EntryPoint = "URLDownloadToFileW", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int URLDownloadToFile(int pCaller, string srcURL,
string dstFile, int Reserved, int CallBack);
static void Main(string[] args)
{
// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://site.domain.com/operations/reporting/report-run.asp?reportid=720");
////webRequest.Proxy = webProxy;
string appname = Environment.GetCommandLineArgs()[0];
if (args.Count() < 1)
{
Console.WriteLine("Type: \"{0}\" -h for help on usage.\n", appname);
return;
}
if (args.Count() > 0)
foreach (var s in args)
if (s.Contains("-h") || s.Contains("/h") || s.Contains("-?") || s.Contains("/?"))
{
Console.WriteLine("\nUsage: {0} [-rfupv] <values>\n", appname);
Console.WriteLine("\n -r report_link ");
Console.WriteLine(" -f output_file ");
Console.WriteLine(" -u username ");
Console.WriteLine(" -p password ");
Console.WriteLine(" -t time_delay - seconds to wait before sending key strokes");
Console.WriteLine(" -v verbose output to console (for debugging)");
Console.WriteLine(" -h|? Display this info and exit.");
return;
}
try
{
if (args.Any(x => x.Contains("-f")))
{
int i = 0;
while (!args[i].Contains("-f")) i++;
filename =args[i + 1];
}
else filename = "report.csv";
if (args.Any(x => x.Contains("-r")))
{
int i = 0;
while (!args[i].Contains("-r")) i++;
report = args[i + 1];
}
else report = "http://site.domain.com/operations/reporting/report-run.asp?reportid=720";
if (args.Any(x => x.Contains("-u")))
{
int i = 0;
while (!args[i].Contains("-u")) i++;
username = args[i + 1];
}
else username = "";
if (args.Any(x => x.Contains("-p")))
{
int i = 0;
while (!args[i].Contains("-p")) i++;
password = args[i + 1];
}
else password = "";
if (args.Any(x => x.Contains("-t")))
{
int i = 0;
while (!args[i].Contains("-t")) i++;
t = int.Parse(args[i + 1]);
}
else t = 5;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
if (ex.InnerException != null) Console.WriteLine(ex.InnerException.Message);
return;
}
///////////////////////////////
//////////////////////////////////////////////////////
Console.WriteLine("start");
var th = new Thread(() => {
//WebBrowser
var wb = new SelfAuthenticatingWebBrowser(); // WebBrowser();
wb.Show(); Console.WriteLine(wb.DocumentText);
Console.WriteLine(wb.DocumentText);
wb.DocumentCompleted += browser_DocumentCompleted;
wb.NewWindow += browser_newWindow;
wb.ControlAdded += browser_ControlAdded ;
wb.LostFocus += browser_LostFocus;
wb.Navigating += browser_Navigating;
wb.FileDownload += browser_FileDownload;
//wb.Site = new MySitex();
//Console.WriteLine(wb.Site.GetService(typeof(IAuthenticateEx)));//wb.Site.Name
Console.WriteLine(wb.AllowNavigation);
wb.Navigate("about:blank");
object obj = wb.ActiveXInstance;
IOleObject oc = obj as IOleObject;
oc.SetClientSite(wb as IOleClientSite);
//this.Site = this as ISite;
System.IntPtr ppvServiceProvider;
IServiceProvider sp = wb as IServiceProvider;
sp.QueryService(ref SelfAuthenticatingWebBrowser.SID_IAuthenticate, ref SelfAuthenticatingWebBrowser.IID_IAuthenticate, out ppvServiceProvider);
wb.Navigate(report);
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
Console.WriteLine("end");
}
static void browser_Navigating(object sender, EventArgs e)
{
Console.WriteLine("navigating..." );
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
//foreach (var x in s.Controls)
// Console.WriteLine(x.ToString());
//foreach(Form x in Application.OpenForms)
// Console.WriteLine(x.Name);
if (false)//(send)
{
send = false;
var thekeys = new Thread(() =>
{
Thread.Sleep(t*1000);
if (username != "")
{
Console.WriteLine("sending username key strokes");
SendKeys.SendWait(username);
SendKeys.SendWait("{TAB}");
Console.WriteLine("sent");
}
if (password != "")
{
Console.WriteLine("sending password key strokes");
SendKeys.SendWait(password);
SendKeys.SendWait("{ENTER}");
Console.WriteLine("sent");
}
});
thekeys.Start();
}
}
static void browser_FileDownload(object sender, EventArgs e)
{
if(verbose) Console.WriteLine("FileDownload : " + e.ToString());
var s = sender as WebBrowser;
if (verbose) Console.WriteLine(s.DocumentTitle + s.Name + s.Url); //Console.ReadKey();
}
static void browser_LostFocus(object sender, EventArgs e)
{
Console.WriteLine("lost focus : " + e.ToString());
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
}
static void browser_ControlAdded(object sender, ControlEventArgs e)
{
Console.WriteLine("control added : " + e.ToString());
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
}
static void browser_newWindow(object sender, CancelEventArgs e)
{
Console.WriteLine("new : " + e.ToString());
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
}
static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var br = sender as WebBrowser;
if (e.Url.ToString()=="about:blank") return;
if (br.Url == e.Url)
{
Console.WriteLine("Navigated to {0}", e.Url);
if (e.Url.ToString() == "http://site.domain.com/operations/reporting/report-generate.asp") submitted = true;
if(verbose) Console.WriteLine(br.DocumentText);
//Console.WriteLine(br.Document.Cookie);
if(!clicked)
foreach (HtmlElement x in br.Document.All)
{
// if (x.All == null)
//Console.WriteLine("|{0} {1} {2}| [{3}]\n", x.Id, x.Name, ".",x.GetAttribute("value"));
if (x.Name == "format" && x.GetAttribute("value") == "C") { Console.WriteLine("\n C L I C K !\n"); x.InvokeMember("click"); Thread.Sleep(1000); clicked = true; }
//else foreach (HtmlElement y in x.Document.All)
// Console.WriteLine("|{0} {1} {2}| [{3}]\n", y.Id, y.Name, y.OuterHtml, x.InnerText);
}
if (clicked && !submitted)
{
Console.WriteLine("submitting the report");
if (verbose) Console.WriteLine(" function at: {0}", br.DocumentText.IndexOf("function runReport()"));
//var newtext = br.DocumentText.Replace("value=\"R\" checked", "value=\"R\" ").Replace("value=\"C\"", "value=\"C\" checked");
//Console.WriteLine(" function at: {0}", br.DocumentText.IndexOf("function runReport()"));
br.Document.InvokeScript("runReport");
Console.WriteLine("done");
//Console.WriteLine(br.DocumentText);
}
//if (c == 1)
{
//Console.WriteLine(br.DocumentText);
if (verbose) Console.WriteLine(br.DocumentText.IndexOf("http://"));
if (verbose) Console.WriteLine(br.DocumentText.IndexOf(".csv"));
}
if (verbose) Console.WriteLine("c = {0}", c);
//http://site.domain.com/operations/reporting/csv/Report714_4045373.csv
if (submitted)
{
int start = br.DocumentText.IndexOf("csv/Report");
int end = 0; if (start >= 0) end = br.DocumentText.IndexOf(".csv", start);
if (start > 0 && end > start)
{
if (verbose) Console.WriteLine(br.DocumentText.Substring(start, end - start));
string link = "http://site.domain.com/operations/reporting/" + br.DocumentText.Substring(start, end - start) + ".csv";
Console.WriteLine(link);
//Console.WriteLine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
//Console.WriteLine(System.IO.Directory.GetCurrentDirectory());
if (URLDownloadToFile(0, link, filename, 0, 0) == 0)
Console.WriteLine("The report has been saved as {0}", filename);
else
Console.WriteLine("There was a problem with downloading/saving the report {0}", report);
Application.ExitThread();
}
}
if (verbose) Console.WriteLine("cookies ? {0}, {1}, {2}", br.Document.Cookie == null, br.Document.Cookie == "", br.Document.Cookie);
c++;
if(c>4) Application.ExitThread(); // Stops the thread
}
}
}
}

Streamreader locks file

I have a c# app (Windows Service) that fires a timer event that reads files in a directory and sends out SMS using the data in the files. Next time the event fires, it tries to move the processed files in the "Processed" directory to a "Completed" directory before processing the new files. I keep getting a "File in use by another process" exception, although I am pretty sure that I dispose of everything that uses the files. If I stop the service and start it again, the files is released. Any ideas?
//Code that fires the timer
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace SmsWindowsService
{
public partial class SmsWindowsService : ServiceBase
{
private static System.Timers.Timer aTimer;
public SmsWindowsService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MatterCentreSMSSource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MatterCentreSMSSource", "MatterCentreSMSLog");
}
elMatterCentreSMS.Source = "MatterCentreSMSSource";
elMatterCentreSMS.Log = "MatterCentreSMSLog";
}
protected override void OnStart(string[] args)
{
string logText = string.Empty;
logText = "MatterCentreSMS Service started successfully on " + DateTime.Now;
WriteEventLog(logText);
//Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
//Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
//Set the Interval to 5 minutes.
//aTimer.Interval = 300000;
aTimer.Interval = 60000;
aTimer.Enabled = true;
// If the timer is declared in a long-running method, use
// KeepAlive to prevent garbage collection from occurring
// before the method ends.
//GC.KeepAlive(aTimer);
GC.Collect();
}
protected override void OnStop()
{
string logText = string.Empty;
logText = "MatterCentreSMS Service stopped on " + DateTime.Now;
WriteEventLog(logText);
}
private void WriteEventLog(string logText)
{
elMatterCentreSMS.WriteEntry(logText);
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
string ex = string.Empty;
SendSms s = new SendSms();
ex = s.ProcessSms();
if (ex.Length > 1)
WriteEventLog(ex);
//ex = RestartService("SmsWindowsService", 60000);
//WriteEventLog(ex);
}
public string RestartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
int millisec1 = Environment.TickCount;
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
// count the rest of the timeout
int millisec2 = Environment.TickCount;
timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
return "MatterCentreSMS Service successfully restarted on " + DateTime.Now;
}
catch (Exception e)
{
return Convert.ToString(e);
}
}
}
}
//Code that reads the file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
namespace SmsWindowsService
{
class Message
{
private string filePath;
public Message(string filePath)
{
this.filePath = filePath;
}
public string readSMS(string filePath)
{
const string searchmessage = "[B-->]";
StreamReader smsmessage = new StreamReader(filePath);
try
{
FileInfo filenameinfo = new FileInfo(filePath);
if (filenameinfo.Exists == false)
throw new SMSReaderException(String.Format("SMS Message {0} cannot be found ...", filePath), filePath);
smsmessage = filenameinfo.OpenText();
string smsoutput = smsmessage.ReadToEnd();
int endpos = smsoutput.IndexOf(searchmessage);
smsoutput = smsoutput.Substring(endpos + searchmessage.Length);
smsoutput = smsoutput.Replace("&", "&");
smsoutput = smsoutput.Replace("\"", """);
smsoutput = smsoutput.Replace("'", "'");
filenameinfo = null;
smsmessage.Close();
smsmessage.Dispose();
return smsoutput;
}
catch(Exception e)
{
throw new Exception("Help", e.InnerException);
}
finally
{
smsmessage.Close();
smsmessage.Dispose();
}
}
}
public class SMSReaderException : System.IO.FileNotFoundException
{
public SMSReaderException(string message, string filename)
: base(message, filename)
{
}
}
}
//Code that connects to web service and send sms
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Net;
using System.Configuration;
using SmsWindowsService.EsendexSendSmsService;
namespace SmsWindowsService
{
class SendSms
{
string filePath = string.Empty;
string directoryPath = string.Empty;
string directoryPathProcessing = string.Empty;
string directoryPathCompleted = string.Empty;
string smsLogfileDirectory = string.Empty;
string smsLogfilePath = string.Empty;
string mattercentreSMS = string.Empty;
string messageBody = string.Empty;
string messageId = string.Empty;
string messageStatus = string.Empty;
string dateTodayString = string.Empty;
long mobileNumber;
EsendexSendSmsService.SendService send;
public SendSms()
{
directoryPath = ConfigurationSettings.AppSettings[#"directoryPath"];
directoryPathProcessing = ConfigurationSettings.AppSettings[#"directoryPathProcessing"];
directoryPathCompleted = ConfigurationSettings.AppSettings[#"directoryPathCompleted"];
smsLogfileDirectory = ConfigurationSettings.AppSettings[#"smsLogfileDirectory"];
dateTodayString = DateTime.Now.ToString("yyyy/MM/dd");
smsLogfilePath = smsLogfileDirectory + dateTodayString.Replace(#"/", "_") + ".txt";
send = new EsendexSendSmsService.SendService();
}
public string ProcessSms()
{
string ex = string.Empty;
try
{
DirectoryInfo di = new DirectoryInfo(directoryPathProcessing);
ex = MoveFilesToCompleted(directoryPathProcessing, directoryPathCompleted);
if (ex.Length > 1)
return ex;
ex = MoveFilesToProcessing(directoryPath, directoryPathProcessing);
if (ex.Length > 1)
return ex;
FileInfo[] subFilesProcessing = di.GetFiles();
foreach (FileInfo subFile in subFilesProcessing)
{
filePath = directoryPathProcessing + subFile.Name;
Message sms = new Message(filePath);
mattercentreSMS = sms.readSMS(filePath);
MessageDetails d = new MessageDetails(mattercentreSMS);
mobileNumber = d.GetMobileNumber();
messageBody = d.GetMessageBody();
ex = SetHeader();
if (ex.Length > 1)
return ex;
ex = SetProxy();
if (ex.Length > 1)
return ex;
//Send the message and get the returned messageID and send status
messageId = send.SendMessage(Convert.ToString(mobileNumber), messageBody, EsendexSendSmsService.MessageType.Text);
messageStatus = Convert.ToString(send.GetMessageStatus(messageId));
ex = WriteLogFile(messageId, subFile.Name, messageStatus);
if (ex.Length > 1)
return ex;
send.Dispose();
}
di = null;
subFilesProcessing = null;
return ex;
}
catch (Exception e)
{
return Convert.ToString(e);
}
}
private string MoveFilesToCompleted(string directoryPathProcessing, string directoryPathCompleted)
{
DirectoryInfo din = new DirectoryInfo(directoryPathProcessing);
try
{
FileInfo[] subFiles = din.GetFiles();
foreach (FileInfo subFile in subFiles)
{
subFile.MoveTo(directoryPathCompleted + subFile.Name);
}
subFiles = null;
return "";
}
catch (Exception e)
{
return Convert.ToString(e);
}
finally
{
din = null;
}
}
private string MoveFilesToProcessing(string directoryPath, string directoryPathProcessing)
{
DirectoryInfo din = new DirectoryInfo(directoryPath);
try
{
FileInfo[] subFiles = din.GetFiles();
foreach (FileInfo subFile in subFiles)
{
subFile.MoveTo(directoryPathProcessing + subFile.Name);
}
subFiles = null;
return "";
}
catch (Exception e)
{
return Convert.ToString(e);
}
finally
{
din = null;
}
}
private string SetHeader()
{
try
{
//Setup account details in the header
EsendexSendSmsService.MessengerHeader header = new EsendexSendSmsService.MessengerHeader();
header.Account = ConfigurationSettings.AppSettings[#"smsServiceUrl"];
header.Username = ConfigurationSettings.AppSettings[#"smsServiceUsername"];
header.Password = ConfigurationSettings.AppSettings[#"smsServicePassword"];
// set the SOAP header Authentication values
send.MessengerHeaderValue = header;
return "";
}
catch (Exception e)
{
return Convert.ToString(e);
}
}
private string SetProxy()
{
try
{
//Create a web proxy object as the proxy server block direct request to esendex
WebProxy myProxy = new WebProxy(ConfigurationSettings.AppSettings[#"proxyaddress"], true);
myProxy.Credentials = new NetworkCredential(ConfigurationSettings.AppSettings[#"username"], ConfigurationSettings.AppSettings[#"password"]);
WebRequest.DefaultWebProxy = myProxy;
send.Proxy = myProxy;
return "";
}
catch (Exception e)
{
return Convert.ToString(e);
}
}
private string WriteLogFile(string messageId, string smsFileName, string messageStatus)
{
try
{
if (File.Exists(smsLogfilePath))
{
//file is not empty - append log entry to file
using (StreamWriter writeSmsLog = File.AppendText(smsLogfilePath))
{
writeSmsLog.WriteLine(messageId + " " + smsFileName + " " + DateTime.Now + " " + messageStatus);
writeSmsLog.Close();
}
}
else
{
FileStream fs = File.OpenWrite(smsLogfilePath);
fs.Flush();
fs.Close();
fs.Dispose();
using (StreamWriter writeSmsLog = new StreamWriter(smsLogfilePath, true))
{
writeSmsLog.WriteLine("Message_ID File_Name Date_Sent Status");
writeSmsLog.WriteLine("======================================================================================================================================");
writeSmsLog.WriteLine(messageId + " " + smsFileName + " " + DateTime.Now + " " + messageStatus);
writeSmsLog.Close();
}
}
return "";
}
catch (Exception e)
{
return Convert.ToString(e);
}
}
}
}
Any ideas?
You're running a virus checker in an entirely different process. It is detecting that the file has changed and is locking it momentarily in order to check it to see if the edit you just performed to the file introduced a virus. It'll unlock it in a couple of milliseconds.
Disabling your virus checker is a bad idea. Instead, you're just going to have to live with it; write your code to be robust in a world where there are lots of processes vying for locks on files.
StreamReader smsmessage = new StreamReader(filePath);
try
{
FileInfo filenameinfo = new FileInfo(filePath);
....
smsmessage = filenameinfo.OpenText();
...
You are initializing smsmessage twice, but only disposing one of those instances. The first line constructs a StreamReader, and then you overwrite your reference to that instance with the instance created by filenameinfo.OpenText(). That leaves you with an instance that no longer has any references and hasn't been disposed. That instance might be holding a lock on the file and you have no guarantees on when it will be disposed. Even if it isn't holding a lock, you should still fix this.

Categories