Every once in a while, StorageFiles get locked and I get an UnauthorizedAccessException when trying to overwrite them. I cannot replicate this, it only happens randomly. This is the code for creating files:
using (var stream = new MemoryStream())
{
// ...populate stream with serialized data...
StorageFile file;
Stream fileStream;
try
{
file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
}
catch (UnauthorizedAccessException ex)
{
Debug.WriteLine("Access denied on file {0}", fileName);
return;
}
fileStream = await file.OpenStreamForWriteAsync();
using (fileStream)
{
stream.Seek(0, SeekOrigin.Begin);
await stream.CopyToAsync(fileStream);
await fileStream.FlushAsync();
}
}
Once a file starts throwing UnauthorizedAccessException, it will always throw it. As if the system has the file locked and I cannot touch it. I have to uninstall the application and rebuild.
When I open the file in my document, I can see that data there. Everything is fine. It was written successfully.
Can anyone see a problem with my code?
Are you saving the file token in the future access list? I ran into this problem when loading files and trying to save updates later. Once I started using the future access list, the problems went away.
http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.accesscache.storageitemaccesslist
It might be the case when the same file is being accessed from two different points in the code at the same time.
Related
I’m having an issue using EPPlus 6.0.6 on the server within an IIS process. I upload an xlsx to the IIS server, then call the method to process the file (read from the file only.) When finished, I want to remove the file from the server folder, but get the error:
The process cannot access the file because it is being used by another process.
Calling method:
Processor processor = new Processor (filename)
{
Await processor.Process();
try { File.Delete(selectedFile); txtStatusMsg += “Cleanup Succeeded”;}
catch (Exception e){ txtStatusMsg += $#"Cleanup Failed - {e.Message}"; }
// error occurs
// ex.message is
// The process cannot access the file because it is being used by another process.
}
The Process method has:
using (FileStream fs =
new FileStream(filename ,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (ExcelPackage srcPkg = new ExcelPackage(fs))
{
// read from the file
foreach (ExcelWorksheet srcWs in srcPkg.Workbook.Worksheets) ...
}
}
The file is still locked; I would expect the srcPkg to be disposed after the using block, and fs to be closed/disposed after its using block.
I’ve tried
srcPkg.Dispose();
after the for loop, and
fs.Close();
After the srcPkg using but neither help. Restarting IIS releases the file.
Can i force the file to be unlocked in some way?
Team,
I have a blazor web assembly app, which upload the file and process it later. However , I would like to know the base path of the file from where it it picked in the machine.
My code goes as follows . Does anyone has idea to get the file path such as "C:\myfile.txt".
With the File object, I cannot achieve the full path, I can access only its memory stream.
<h1>FILE UPLAOD </h1>
<InputFile OnChange="HandleSelection" ></InputFile>
#code
{
string status;
async Task HandleSelection(IFileListEntry[] files)
{
var file = files.FirstOrDefault();
if (file != null)
{
// Just load into .NET memory to show it can be done
// Alternatively it could be saved to disk, or parsed in memory, or similar
var ms = new MemoryStream();
await file.Data.CopyToAsync(ms);
Console.WriteLine(ms);
status = $"Finished loading {file.Size} bytes from {file.Name}";
var content = new MultipartFormDataContent
{
{ new ByteArrayContent(ms.GetBuffer()),"\"upload\"", file.Name}
};
await client.PostAsync("upload", content);
}
}
}
Even if you get the fullpath (C:\myfile.txt") file won't load
by default, all browser has a security mechanism that any local disk file won't be loaded into a website until you disable that security for your website
I try make one program for download one .exe file and run for help in my job.
But idk how to make this, i'm new in VB.
I am using this code, as shown in the Visual Basic document reference:
My.Computer.Network.DownloadFile _
("http://www.cohowinery.com/downloads/WineList.txt", _
"C:\Documents and Settings\All Users\Documents\WineList.txt")
But when I try to download an .exe file, the entire file doesn't complete and I the file is only 1 kb after download.
The webclient should be the way to go a comment above highlights that too.
This is an example from another question:
Either use sync method:
public void DownloadFile()
{
using(var client = new WebClient())
{
client.DownloadFile(new Uri("http://www.FileServerFullOfFiles.net/download/test.exe"), "test.exe");
}
}
Or use new async-await approach:
public async Task DownloadFileAsync()
{
using(var client = new WebClient())
{
await client.DownloadFileTaskAsync(new Uri("http://www.FileServerFullOfFiles.net/download/test.exe"), "test.exe");
}
}
Then call this method like this:
await DownloadFileAsync();
Open up the .exe file you are trying to download in a text editor like NotePad. Odds are what is being downloaded is an HTML page showing some kind of error message like 404 not found.
Another possibility might be that AntiVirus software is moving the original EXE into quarantine and replacing it with a Quarantine MetaData file.
If the file does actually contain binary content your connection could be getting interrupted but odds are if this happened an exception would be thrown.
I'm trying to get file uploads working with the new OneDrive API. I'm starting out with just simple files (i.e. < 100MB) with the intention of progressing to resumable uploads once I've got the simple ones working!
I've tried using http://onedrive.github.io/items/upload_put.htm but I'm getting 403 back. I thought that this might be because the file didn't already exist but I've uploaded the file using the OneDrive web UI successfully and the code still can't upload the file.
The URL I'm using is something like:
https://api.onedrive.com/v1.0/drive/root:/:/content?access_token=
The C# code is:
using (Stream fileStream = await file.OpenStreamForReadAsync())
{
try
{
HttpStreamContent streamContent = new HttpStreamContent(fileStream.AsInputStream());
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, oneDriveURI);
request.Content = streamContent;
request.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("application/octet-stream");
HttpResponseMessage response = await client.SendRequestAsync(request);
Debug.WriteLine("UploadFileToOneDrive: response = {0}", response.StatusCode);
}
catch (Exception ex)
{
Debug.WriteLine("UploadFileToOneDrive failed with exception {0}", ex.Message);
}
}
What have I got wrong/misunderstood? The API documentation needs a LOT more examples :-(
403 error code is related to permissions so it could be possible that you may have forgotten to include the proper scopes to upload the file. When you send your OAuth request, you'll want to also include "onedrive.readwrite" as one of the scopes.
GET https://login.live.com/oauth20_authorize.srf?client_id={client_id}&scope={scope}&response_type=token&redirect_uri={redirect_uri}
More scopes can be found at "http://onedrive.github.io/auth/msa_oauth.htm". I hope that helps.
I need to make my CF app self-updating through the web service.
I found one article on MSDN from 2003 that explains it quite well. However, I would like to talk practice here. Anyone really done it before or does everyone rely on third party solutions?
I have been specifically asked to do it this way, so if you know of any tips/caveats, any info is appreciated.
Thanks!
This is relatively easy to do. Basically, your application calls a web service to compare its version with the version available on the server. If the server version is newer, your application downloads the new EXE as a byte[] array.
Next, because you can't delete or overwrite a running EXE file, your application renames its original EXE file to something like "MyApplication.old" (the OS allows this, fortunately). Your app then saves the downloaded byte[] array in the same folder as the original EXE file, and with the same original name (e.g. "MyApplication.exe"). You then display a message to the user (e.g. "new version detected, please restart") and close.
When the user restarts the app, it will be the new version they're starting. The new version deletes the old file ("MyApplication.old") and the update is complete.
Having an application update itself without requiring the user to restart is a huge pain in the butt (you have to kick off a separate process to do the updating, which means a separate updater application that cannot itself be auto-updated) and I've never been able to make it work 100% reliably. I've never had a customer complain about the required restart.
I asked this same question a while back:
How to Auto-Update Windows Mobile application
Basically you need two applications.
App1: Launches the actual application, but also checks for a CAB file (installer). If the cab file is there, it executes the CAB file.
App2: Actual application. It will call a web service, passing a version number to the service and retrieve a URL back if a new version exists (). Once downloaded, you can optionally install the cab file and shut down.
One potiencial issue: if you have files that one install puts on the file system, but can't overwrite (database file, log, etc), you will need two separate installs.
To install a cab: look up wceload.exe http://msdn.microsoft.com/en-us/library/bb158700.aspx
private static bool LaunchInstaller(string cabFile)
{
// Info on WceLoad.exe
//http://msdn.microsoft.com/en-us/library/bb158700.aspx
const string installerExe = "\\windows\\wceload.exe";
const string processOptions = "";
try
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = installerExe;
processInfo.Arguments = processOptions + " \"" + cabFile + "\"";
var process = Process.Start(processInfo);
if (process != null)
{
process.WaitForExit();
}
return InstallationSuccessCheck(cabFile);
}
catch (Exception e)
{
MessageBox.Show("Sorry, for some reason this installation failed.\n" + e.Message);
Console.WriteLine(e);
throw;
}
}
private static bool InstallationSuccessCheck(string cabFile)
{
if (File.Exists(cabFile))
{
MessageBox.Show("Something in the install went wrong. Please contact support.");
return false;
}
return true;
}
To get the version number: Assembly.GetExecutingAssembly().GetName().Version.ToString()
To download a cab:
public void DownloadUpdatedVersion(string updateUrl)
{
var request = WebRequest.Create(updateUrl);
request.Credentials = CredentialCache.DefaultCredentials;
var response = request.GetResponse();
try
{
var dataStream = response.GetResponseStream();
string fileName = GetFileName();
var fileStream = new FileStream(fileName, FileMode.CreateNew);
ReadWriteStream(dataStream, fileStream);
}
finally
{
response.Close();
}
}
What exactly do you mean by "self-updating"? If you're referring to configuration or data, then webservices should work great. If you're talking about automatically downloading and installing a new version of itself, that's a different story.
Found this downloadable sample from Microsoft- looks like it should help.
If you want to use a third-party component, have a look at AppToDate developed by the guys at MoDaCo.