Epplus - Reading through filestream. The process cannot access the file because it is being used by another process. - - epplus

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?

Related

Is the below code correct to connect to a remote Linux host and get few tasks done using Apache Mina?

I want to switch from Jsch to Apache Mina to query remote Linux hosts and to get the few tasks done.
I need to achieve things like list files of a remote host, change directory, get file contents, put a file into the remote host etc.,
I am able to successfully connect and execute a few shell commands using session.executeRemoteCommand().
public byte[] getRemoteFileContent(String argDirectory, String fileName)
throws SftpException, IOException {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
StringBuilder cmdBuilder = new StringBuilder("cat" + SPACE + remoteHomeDirectory);
cmdBuilder.append(argDirectory);
cmdBuilder.append(fileName);
_session.executeRemoteCommand(cmdBuilder.toString(), stdout, null, null);
return stdout.toByteArray();
}
public void connect()
throws IOException {
_client = SshClient.setUpDefaultClient();
_client.start();
ConnectFuture connectFuture = _client.connect(_username, _host, portNumber);
connectFuture.await();
_session = connectFuture.getSession();
shellChannel = _session.createShellChannel();
_session.addPasswordIdentity(_password);
// TODO : fix timeout
_session.auth().verify(Integer.MAX_VALUE);
_channel.waitFor(ccEvents, 200);
}
I have the following questions,
How can I send a ZIP file to a remote host much easily in API level (not the Shell commands level)? And all other operations in API level.
Can I secure a connection between my localhost and remote through a certificate?
As of now, I am using SSHD-CORE and SSHD-COMMON version 2.2.0. Are these libraries enough or do I need to include any other libraries?
executeRemoteCommand() is stateless how can I maintain a state?
I needed sshd-sftp and its APIs to get the file transfer work.
Below code gets the proper API,
sftpClient = SftpClientFactory.instance().createSftpClient(clientSession);
On sftpClinet I called read() and write() methods get the task done. This answers my question fully.

how to download exe files in vb.net (Visual Studio 2015)

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.

Load stream in Epplus causes disk write error

Im upload an excel file and trying to load it into a ExcelPackage. Like this
public static void ImportStuff(Stream stream)
{
using (ExcelPackage package = new ExcelPackage())
{
package.Load(stream);
...
My calling method gets the stream from an uploaded file
public async Task<ActionResult> UploadCsv(int Id, HttpPostedFileBase myfile)
{
ImportProducts(myfile.InputStream);
}
This will cause a A disk error occurred during a write operation. (Exception from HRESULT: 0x8003001D (STG_E_WRITEFAULT))
Why do a get a write error when I am trying to load something?
I was trying to upload a csv file. Not a xslx file. Could have hoped for a more descriptive error message but it is working.

Replacing files throws UnauthorizedAccessException in WinRT / Win8

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.

Self updating .net CF application

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.