Response is not available in context? How to solve it? - c#

I save a pdf file to stream. I want to save the stream to Response stream. But it always throw error:Response is not available in contex.
Here is the code:
using System;
using System.Threading;
using System.IO;
using Spire.Pdf;
namespace SingleThreadTest
{
public partial class Test : System.Web.UI.Page
{
//[STAThread]
protected void Page_Load(object sender, EventArgs e)
{
}
[STAThread]
protected void Button1_Click(object sender, EventArgs e)
{
////new a thread
ThreadStart threadStart = HTMLToPDF;
Thread thread = new Thread(threadStart);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
void HTMLToPDF()
{
PdfDocument doc = new PdfDocument();
String url = "http://www.e-iceblue.com/";
doc.LoadFromHTML(url, false, true, true);
Response.ClearContent();
Response.ClearHeaders();
Response.BufferOutput = true;
Response.ContentType = "application/pdf";
using (MemoryStream pdfStream = new MemoryStream())
{
doc.SaveToStream(pdfStream);
using (MemoryStream ms = new MemoryStream())
{
//ms.WriteTo(Response.OutputStream);
Response.OutputStream.Write(pdfStream.ToArray(), 0, pdfStream.ToArray().Length);
}
}
doc.SaveToHttpResponse("Test.pdf", Response, HttpReadType.Save);
doc.Close();
}
}
}
I want to sent client an attachment. How to acheive it??(The above code i use the third component of Spire.PDF).
Thanks in advance.

You are starting new thread to process request, but your original thread likely continues execution and successfully terminates request before your new thread even gets to doing something with the response. You have to wait for completion of the new thread in the original thread (you may be able to creatively use asynchronous pages to not block original thread http://msdn.microsoft.com/en-us/magazine/cc163725.aspx).

I had a similar task. I had a dataset and I needed to return to the client excel file.
I solved with the AXD handler. Add to web config reference to AXD.
See example
<httpHandlers>
<add verb="GET,POST" path="Export.axd" type="YourNameSpace.ExportHandler, YouDLL"/>
</httpHandlers>
See below the code
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Spire;
using Spire.Xls;
namespace SD.Reval.Admin.Services
{
public class ExportHandler : IHttpHandler
{
virtual public bool IsReusable
{
get { return true; }
}
virtual public void ProcessRequest(HttpContext context)
{
try
{
Workbook workbook = new Workbook();
Worksheet worksheet;
int counter = 0;
string methodName = HttpContext.Current.Request.QueryString["methodName"];
string fileName = HttpContext.Current.Request.QueryString["fileName"];
string parameters = HttpContext.Current.Request.QueryString["params"];
if (parameters == null)
parameters = HttpContext.Current.Request.Form["params"];
int workSheetCount = workbook.Worksheets.Count;
string tableName = string.Empty ;
if (methodName.Length > 0 && fileName.Length > 0)
{
DataSet dataSet = (DataSet)ServiceInterface.InternalGenericInvoke(methodName, parameters);
foreach (DataTable dt in dataSet.Tables)
{
if (dt.Columns.Count > 0)
{
tableName = dt.TableName ;
if (counter >= workSheetCount)
worksheet=workbook.Worksheets.Add(tableName);
else
{
worksheet = workbook.Worksheets[counter];
worksheet.Name = tableName;
}
worksheet.InsertDataTable(dt, true, 4, 1, -1, -1);
counter++;
worksheet.AllocatedRange.AutoFitColumns();
worksheet.AllocatedRange.AutoFitRows();
worksheet.Pictures.Add(1, 1, SD.Reval.Admin.Services.ResourceFile.logo_reval );
//Sets header style
CellStyle styleHeader = worksheet.Rows[0].Style;
styleHeader.Borders[BordersLineType.EdgeLeft].LineStyle = LineStyleType.Thin;
styleHeader.Borders[BordersLineType.EdgeRight].LineStyle = LineStyleType.Thin;
styleHeader.Borders[BordersLineType.EdgeTop].LineStyle = LineStyleType.Thin;
styleHeader.Borders[BordersLineType.EdgeBottom].LineStyle = LineStyleType.Thin;
styleHeader.VerticalAlignment = VerticalAlignType.Center;
styleHeader.KnownColor = ExcelColors.Green;
styleHeader.Font.KnownColor = ExcelColors.White;
styleHeader.Font.IsBold = true;
}
}
fileName = fileName + ".xls";
workbook.SaveToHttpResponse(fileName, context.Response);
context.Response.Buffer = true;
context.Response.ContentType = "application/x-msdownload";
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName );
}
}
catch (Exception ex)
{
Log.WriteLog(ex);
throw new ApplicationException("The epxport process failed", ex);
}
finally
{
}
}
}
}

Related

Extract Frames from Video C#

I'm trying to make an app that use the camera to record a video and process the images of the video. Here is what I want. First, my app records a 10 second video with Torch. Second, I use a method to playback the video to see what I record.
I'm stuck on three things.
How can I convert my video into individual frames (images)?
Is it possible to asynchronously convert the video while it is being recorded?
When I do convert the video into individual frames, how do I work with them? Are they JPEGs? Can I simply display them as images? Etc.
Main code:
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace App3
{
public sealed partial class MainPage : Page
{
DispatcherTimer D;
double basetimer = 0;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
D = new DispatcherTimer();
D.Interval = new TimeSpan(0, 0, 1);
D.Tick += timer_Tick;
txt.Text = basetimer.ToString();
Play.IsEnabled = false;
}
public Library Library = new Library();
public object PreviewImage { get; private set; }
void timer_Tick(object sender, object e)
{
basetimer = basetimer - 1;
txt.Text = basetimer.ToString();
if (basetimer == 0)
{
D.Stop();
Preview.Source = null;
Library.Stop();
Record.IsEnabled = false;
Play.IsEnabled = true;
Clear.IsEnabled = true;
if (Library._tc.Enabled)
{
Library._tc.Enabled = false;
}
}
}
private void Record_Click(object sender, RoutedEventArgs e)
{
if (Library.Recording)
{
Preview.Source = null;
Library.Stop();
Record.Icon = new SymbolIcon(Symbol.Video);
}
else
{
basetimer = 11;
D.Start();
//D.Tick += timer_Tick;
Display.Source = null;
Library.Record(Preview);
Record.Icon = new SymbolIcon(Symbol.VideoChat);
Record.IsEnabled = false;
Play.IsEnabled = false;
}
}
private async void Play_Click(object sender, RoutedEventArgs e)
{
await Library.Play(Dispatcher, Display);
//Extract_Image_From_Video(Library.buffer);
}
private void Clear_Click(object sender, RoutedEventArgs e)
{
Display.Source = null;
Record.Icon = new SymbolIcon(Symbol.Video);
txt.Text = "0";
basetimer= 0;
Play.IsEnabled = false;
Record.IsEnabled =true;
if (Library.capture != null)
{
D.Stop();
Library.Recording = false;
Preview.Source = null;
Library.capture.Dispose();
Library.capture = null;
basetimer = 11;
}
}
}
}
Library Class:
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.Devices;
using Windows.Media.MediaProperties;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Graphics.Imaging;
using Emgu.CV.Structure;
using Emgu.CV;
using System.Collections.Generic;
public class Library
{
private const string videoFilename = "video.mp4";
private string filename;
public MediaCapture capture;
public InMemoryRandomAccessStream buffer;
public static bool Recording;
public TorchControl _tc;
public int basetimer ;
public async Task<bool> init()
{
if (buffer != null)
{
buffer.Dispose();
}
buffer = new InMemoryRandomAccessStream();
if (capture != null)
{
capture.Dispose();
}
try
{
if (capture == null)
{
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
DeviceInformation cameraDevice =
allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null &&
x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
capture = new MediaCapture();
var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
// Initialize
try
{
await capture.InitializeAsync(mediaInitSettings);
var videoDev = capture.VideoDeviceController;
_tc = videoDev.TorchControl;
Recording = false;
_tc.Enabled = false;
}
catch (UnauthorizedAccessException)
{
Debug.WriteLine("UnauthorizedAccessExeption>>");
}
catch (Exception ex)
{
Debug.WriteLine("Exception when initializing MediaCapture with {0}: {1}", cameraDevice.Id, ex.ToString());
}
}
capture.Failed += (MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs) =>
{
Recording = false;
_tc.Enabled = false;
throw new Exception(string.Format("Code: {0}. {1}", errorEventArgs.Code, errorEventArgs.Message));
};
}
catch (Exception ex)
{
if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UnauthorizedAccessException))
{
throw ex.InnerException;
}
throw;
}
return true;
}
public async void Record(CaptureElement preview)
{
await init();
preview.Source = capture;
await capture.StartPreviewAsync();
await capture.StartRecordToStreamAsync(MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), buffer);
if (Recording) throw new InvalidOperationException("cannot excute two records at the same time");
Recording = true;
_tc.Enabled = true;
}
public async void Stop()
{
await capture.StopRecordAsync();
Recording = false;
_tc.Enabled = false;
}
public async Task Play(CoreDispatcher dispatcher, MediaElement playback)
{
IRandomAccessStream video = buffer.CloneStream();
if (video == null) throw new ArgumentNullException("buffer");
StorageFolder storageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
if (!string.IsNullOrEmpty(filename))
{
StorageFile original = await storageFolder.GetFileAsync(filename);
await original.DeleteAsync();
}
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
StorageFile storageFile = await storageFolder.CreateFileAsync(videoFilename, CreationCollisionOption.GenerateUniqueName);
filename = storageFile.Name;
using (IRandomAccessStream fileStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(video.GetInputStreamAt(0), fileStream.GetOutputStreamAt(0));
await video.FlushAsync();
video.Dispose();
}
IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read);
playback.SetSource(stream, storageFile.FileType);
playback.Play();
});
}
I ended up using MediaToolkit to solve a similar problem after having a ton of trouble with Accord.
I needed to save an image for every second of a video:
using (var engine = new Engine())
{
var mp4 = new MediaFile { Filename = mp4FilePath };
engine.GetMetadata(mp4);
var i = 0;
while (i < mp4.Metadata.Duration.TotalSeconds)
{
var options = new ConversionOptions { Seek = TimeSpan.FromSeconds(i) };
var outputFile = new MediaFile { Filename = string.Format("{0}\\image-{1}.jpeg", outputPath, i) };
engine.GetThumbnail(mp4, outputFile, options);
i++;
}
}
Hope this helps someone some day.
UPDATE for .NET 5:
Recently, I have needed to update this code to work in .NET 5. To do so, I am using MediaToolkit.NetCore, which has been in preview for over a year. Also note: you will need to make the latest ffmpeg, including all 3 .exe files (ffmpeg, ffplay, ffprobe) available to your app.
Without further ado, here is the updated code:
// _env is the injected IWebHostEnvironment
// _tempPath is temporary file storage
var ffmpegPath = Path.Combine(_env.ContentRootPath, "<path-to-ffmpeg.exe>");
var mediaToolkitService = MediaToolkitService.CreateInstance(ffmpegPath);
var metadataTask = new FfTaskGetMetadata(_tempFile);
var metadata = await mediaToolkitService.ExecuteAsync(metadataTask);
var i = 0;
while (i < metadata.Metadata.Streams.First().DurationTs)
{
var outputFile = string.Format("{0}\\image-{1:0000}.jpeg", _imageDir, i);
var thumbTask = new FfTaskSaveThumbnail(_tempFile, outputFile, TimeSpan.FromSeconds(i));
_ = await mediaToolkitService.ExecuteAsync(thumbTask);
i++;
}
I figured this out just yesterday.
Here is full and easy to understand example with picking video file and saving snapshot in 1st second of video.
You can take parts that fits your project and change some of them (i.e. getting video resolution from camera)
1) and 3)
TimeSpan timeOfFrame = new TimeSpan(0, 0, 1);
//pick mp4 file
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
picker.FileTypeFilter.Add(".mp4");
StorageFile pickedFile = await picker.PickSingleFileAsync();
if (pickedFile == null)
{
return;
}
///
//Get video resolution
List<string> encodingPropertiesToRetrieve = new List<string>();
encodingPropertiesToRetrieve.Add("System.Video.FrameHeight");
encodingPropertiesToRetrieve.Add("System.Video.FrameWidth");
IDictionary<string, object> encodingProperties = await pickedFile.Properties.RetrievePropertiesAsync(encodingPropertiesToRetrieve);
uint frameHeight = (uint)encodingProperties["System.Video.FrameHeight"];
uint frameWidth = (uint)encodingProperties["System.Video.FrameWidth"];
///
//Use Windows.Media.Editing to get ImageStream
var clip = await MediaClip.CreateFromFileAsync(pickedFile);
var composition = new MediaComposition();
composition.Clips.Add(clip);
var imageStream = await composition.GetThumbnailAsync(timeOfFrame, (int)frameWidth, (int)frameHeight, VideoFramePrecision.NearestFrame);
///
//generate bitmap
var writableBitmap = new WriteableBitmap((int)frameWidth, (int)frameHeight);
writableBitmap.SetSource(imageStream);
//generate some random name for file in PicturesLibrary
var saveAsTarget = await KnownFolders.PicturesLibrary.CreateFileAsync("IMG" + Guid.NewGuid().ToString().Substring(0, 4) + ".jpg");
//get stream from bitmap
Stream stream = writableBitmap.PixelBuffer.AsStream();
byte[] pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);
using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, writeStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)writableBitmap.PixelWidth,
(uint)writableBitmap.PixelHeight,
96,
96,
pixels);
await encoder.FlushAsync();
using (var outputStream = writeStream.GetOutputStreamAt(0))
{
await outputStream.FlushAsync();
}
}
If you want to display frames in xaml Image, you should use imageStream
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(imageStream);
XAMLImage.Source = bitmapImage;
If you want to extract more frames, there is also composition.GetThumbnailsAsync
2) Use your mediaCapture, when your timer is ticking
EDIT:
used includes:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Media.Editing;
using Windows.Storage;
using Windows.UI.Xaml.Media.Imaging;
Use ffmpeg and install Accord.Video.FFMPEG
using (var vFReader = new VideoFileReader())
{
vFReader.Open("video.mp4");
for (int i = 0; i < vFReader.FrameCount; i++)
{
Bitmap bmpBaseOriginal = vFReader.ReadVideoFrame();
}
vFReader.Close();
}
Another one way to get it :
I used FFMpegCore, official docker image with .net core 3.1 + ubuntu (list of available images)
Dockerfile :
FROM mcr.microsoft.com/dotnet/runtime:3.1-bionic
RUN apt-get update && apt-get install -y ffmpeg libgdiplus
COPY bin/Release/netcoreapp3.1/publish/ App/
WORKDIR /App
ENTRYPOINT ["dotnet", "YouConsoleAppNameHere.dll"]
short code version:
GlobalFFOptions.Configure(new FFOptions { BinaryFolder = "/usr/bin", TemporaryFilesFolder = "/tmp" }); //configuring ffmpeg location
string filePath = AppContext.BaseDirectory + "sample.mp4";
FFMpegArguments.FromFileInput(filePath).OutputToFile("tmp/Video/Frame%05d.png", true, Options => { Options.WithVideoCodec(VideoCodec.Png); }).ProcessSynchronously();
extended version (with some console logs):
using FFMpegCore;
using FFMpegCore.Enums;
...
GlobalFFOptions.Configure(new FFOptions { BinaryFolder = "/usr/bin", TemporaryFilesFolder = "/tmp" }); //configuring ffmpeg location
string filePath = AppContext.BaseDirectory + "sample.mp4";
Console.WriteLine(filePath) ;
Console.WriteLine(File.Exists(filePath));
var mediaInfo = FFProbe.Analyse(filePath);
Console.WriteLine("mp4 duration : " + mediaInfo.Duration);
Directory.CreateDirectory("tmp");
Directory.CreateDirectory("tmp/Video");
Console.WriteLine("started " + DateTime.Now.ToLongTimeString());
FFMpegArguments.FromFileInput(filePath).OutputToFile("tmp/Video/Frame%05d.png", true, Options => { Options.WithVideoCodec(VideoCodec.Png); }).ProcessSynchronously();
Console.WriteLine("processed " + DateTime.Now.ToLongTimeString());
Console.WriteLine(string.Join(", ", Directory.EnumerateFiles("tmp/Video/")));
As a result - png files will be extracted to tmp/Video folder. Of course, you can do the same without docker if you need.

capture an image using c sharp

I have designed a c sharp application which captures an image using the laptop camera,save it ,and sends a copy via an email with the help of Dynamsoft Dynamic .NET TWAIN 5.3 Trial .... when I run the program from the visual studio it works fine,but when I copy and paste the .exe file outside the program directory it does not work and a message saying "program_name has stopped working "appears.and that is my code:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Dynamsoft.DotNet.TWAIN.Enums;
using Dynamsoft.DotNet.TWAIN.WebCamera;
using System.Net.Mail;
using System.IO;
using System.Collections;
namespace captureImageOfMyLaptopUser
{
public partial class Form1 : Form
{
string receiverId;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dynamicDotNetTwain1.IfShowUI = true;
dynamicDotNetTwain1.SupportedDeviceType = EnumSupportedDeviceType.SDT_WEBCAM;
dynamicDotNetTwain1.IfThrowException = true;
if (!Directory.Exists("d:\\WhoOpenedMyLaptop\\Images"))
{
Directory.CreateDirectory("d:\\WhoOpenedMyLaptop");
}
string[] filePaths = Directory.GetFiles(#"d:\WhoOpenedMyLaptop");
ArrayList list = new ArrayList();
int num=0;
foreach (string path in filePaths)
{
int l = path.Length;
num = int.Parse(path.Substring(24, l - 28));
list.Add(num);
}
int[] array = list.ToArray(typeof(int)) as int[];
if (array.Length > 0)
{
num = array.Max();
}
else
{
num=0;
}
string fileName = "d:\\WhoOpenedMyLaptop\\pic" + (num + 1).ToString() + ".pdf";
turnOnCamera();
captureImage();
saveImage(fileName);
sendingTheImage(fileName);
}
private void captureImage()
{
try
{
dynamicDotNetTwain1.EnableSource();
}
catch (Exception)
{
MessageBox.Show("error");
}
}
private void turnOnCamera()
{
try
{
dynamicDotNetTwain1.SelectSourceByIndex(0) ;
dynamicDotNetTwain1.SetVideoContainer(pictureBox1);
dynamicDotNetTwain1.OpenSource();
int count = dynamicDotNetTwain1.ResolutionForCamList.Count;
for (int j = 0; j < count; j++)
{
string tempHeight = dynamicDotNetTwain1.ResolutionForCamList[j].Height.ToString();
string tempWidth = dynamicDotNetTwain1.ResolutionForCamList[j].Width.ToString();
string tempResolution = tempWidth + "X" + tempHeight;
comboResolution.Items.Insert(j, tempResolution);
comboResolution.SelectedIndex = 0;
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
}
private void saveImage(string imagePath)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.FileName = imagePath;
saveFileDialog.Filter = "pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
dynamicDotNetTwain1.SaveAllAsPDF(saveFileDialog.FileName);
}
private void sendingTheImage(string path)
{
readEmailIdFromTextFile();
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("seewhoopenedyourlaptop#gmail.com");
mail.To.Add(receiverId);
string date = DateTime.Now.ToString();
System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment(path);
mail.Attachments.Add(attachment);
mail.Subject = "لقد قام هذا الشخص بفتح جهازك ";
mail.Body = "التوقيت : " + date;
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("seewhoopenedyourlaptop", "mylaptopcamera");
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
// MessageBox.Show("mail Send");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void readEmailIdFromTextFile()
{
String line;
StreamReader sr = new StreamReader("C:\\Program Files\\WhoOpenedMyLaptop\\data.txt");
line = sr.ReadLine();
receiverId = line;
sr.Close();
}
}
}
You should copy the executable files together with all dll files since it depends on them. You can go to references and then select all libraries and at the atributes, change to copy always, then cleanup the project and then build the project, do not run, copy all content of the folder to a new location and open the executable file, it should run

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());
}
}
}
}

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.

C# Auto Update Program

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.

Categories