I am in process of building an app which writes data continuously to a file. When I start the program the file is created and starts being written to.
However I noticed that sometimes if I have Windows Explorer open, access to the file is denied to my app, and an error is thrown.
fs = new System.IO.FileStream(location,
System.IO.FileMode.Open,
System.IO.FileAccess.Write,
System.IO.FileShare.ReadWrite);
So how do I restrict access to this file so only my app can access it, not any other programs?
You can change the last parameter from System.IO.FileShare.ReadWrite to System.IO.FileShare.None.
That locks the file in location exclusively as long as this stream is open and no other app can read, modify or delete that file except your own FileStream.
In fact this isn't only true for other apps - even your own app can't open another FileStream of that file. So keep it open as long as you need but don't forget to correctly dispose the FileStream after use.
Related
I have a desktop application and below is the flow that is to be followed.
During app initialization, an API should be hit and an excel should downloaded to a shared location. After download is complete the app should read the excel file. This won't be a problem with a single instance of app running. But since this is a desktop app, multiple instances (on different computers) are run, app every time during initialization, downloads the file. I'm using OLE Db engine to read the file and the file is being locked and there 's error "The ole db engine cannot read the file because it is opened by another user " while another instance of the app is opened. How to prevent this?
if (response.Result.IsSuccessStatusCode)
{
using (Stream streamToWriteTo = new FileStream(pathToDownloadReport, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
response.Result.Content.CopyToAsync(streamToWriteTo).Wait();
}
}
If you want to have concurrent access to a file you need to make sure every client only takes a read-lock on the file. With OleDb you can open a connection to the file with ReadOnly access with a connection.
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\path\to\your\exelfile.xlsx;Extended Properties=\"Excel 12.0;IMEX=1;ReadOnly=true;\""
You still need to make sure no one opens the file in Excel.
Since you only can have read-only access to your file, you might as well make a local copy of the file and open that instead. That way locking won't be a problem.
I have a basic UWP app running on Windows 10 on the desktop. The app defines a custom file format and lets the user open and edit documents.
I use a FileOpenPicker to let the user pick the file.
My question is: how can I prevent that the user renames/moves/deletes the document outside of my app (for example in the Windows explorer) while it is open in my app?
Word Mobile locks open documents. If I try to rename an open document in the Windows explorer I get an error:
"The action can't be completed because the file is open in Runtime Broker. Close the file and try again."
I want to achieve the same. I suspect that the Word Mobile app is opening the file in a special mode or locking it somehow. I tried the various Storagefile.OpenXXX() methods, but no luck:
// None of these seem to exclusively lock the file:
stream = await file.OpenStreamForWriteAsync();
stream = await file.OpenTransactedWriteAsync();
stream = await file.OpenAsync(FileAccessMode.ReadWrite);
stream = await file.OpenReadAsync();
I believe this should be the call that you are looking for:
file.OpenAsync(FileAccessMode.Read, StorageOpenOptions.AllowOnlyReaders);
from:
https://learn.microsoft.com/en-us/uwp/api/windows.storage.storageopenoptions?view=winrt-19041
There is a ShareMode that you can set on files, if you set this to "None" then nobody else can open or modify this file as long as you're holding it open:
new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
This uses System.IO which should be available to you. Full documentation here:
https://msdn.microsoft.com/en-us/library/system.io.fileshare(v=vs.110).aspx
Would that help you?
I am trying to open a document with Process.Start in an ASP.NET web application. In this case, I am opening a Word file (.docx), but will be opening any type of file in the future.
My understanding of Process.Start is that the application is determined from the extension of the file path passed as a parameter, and opened.
The code I am using is very simple:
Process.Start("C:\\test.docx");
The file exists, and I am not getting any exceptions when the code is run. However, Word is not opening.
I have monitored my running processes through task manager whilst the code is running, and have noticed that a WINWORD.EXE process is starting with the User Name of the application pool being used (DefaultAppPool) in this case.
Why would the process be starting, but no Word window opening?
Edit: In case there is a better solution, here is my situation:
I am allowing users to upload documents, which are saved in an Oracle database as a BLOB. The user is then able to view their saved documents, and open them. What is the best way to extract a byte array from a BLOB, and open it using the correct application?
When I try to
BULK INSERT table FROM 'c:\file.txt'
I get
Msg 4861, Level 16, State 1, Line 1
Cannot bulk load because the file "c:\file.txt" could not be opened. Operating system error code 32(The process cannot access the file because it is being used by another process.).
error since the file is a log file opened by another process.
However with C# I can open the file with System.IO.FileShare.ReadWrite as:
using (System.IO.FileStream fileStream = new System.IO.FileStream("c:\\file.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite))
{
using (System.IO.StreamReader streamReader = new System.IO.StreamReader(fileStream))
{
file = streamReader.ReadToEnd();
}
}
Is there a way to have that ReadWrite share functionality within SQL Server (bulk insert or any other)?
Thanks
Since you don't have control over the OpenFile flags that SQL Server uses behind the scenes, you may have to copy the file to a temporary file prior to doing the bulk insert.
(Reposted from my answer on DBA.SE since you deleted the question.)
BULK INSERT attempts to take a write lock on the source file to ensure that no other process is concurrently modifying the file while the read occurs. This is done to stabilize the file format, since a read could end up attempting to process a partial line being written by a concurrent writer.
Because the log file is opened for writing by another process already, this is incompatible access, and you get that error.
About the code:
FileAccess determines what you are going to do with the file.
FileShare determines what others are allowed to do with the file while you have it open.
The logging process would use FileAccess.Write or FileAccess.ReadWrite, and given that your code succeeds, probably FileShare.Read -- this would prevent others from writing to the file simultaneously, but allows them to read the contents. Your code only requests read access, and so this is compatible. If you re-run the code and request write access (FileAccess.Write) instead, the code will fail.
To use BULK INSERT to import this file, you'll have to make a copy and import that, then there won't be any file locks involved.
In my case, I want to build my own "drop box" like application which I am going to use as a part of my another project.
Discription:
When a word file is opened in the "drop box" folder(inside the folder where changes to the files, file creations deletions ect.. are identified). pictures, txts, txt updates are uploaded to the server without any issue.
But when it comes to office documents. office document creation is uploaded.
Problem:
when the word file is opened, and do some update and save it. the file can not be uploaded due to permission error. even the opened file can not be copied to another place and then uploaded.
Any one faced this kind of issue, and any sugessions.
But we can manually copy and save a opened and saved(but not closed) to another location
But in the program it is not allowed.
You can create another copy of file, this is important because uploading may be slower and reading shared file may lead to conflicts for Word, so what you can do is, you can create a copy quickly on temp file and upload the temp file.
string tmp = Path.GetTempFileName();
using(Stream s = new FileStream(filePath,
FileMode.Open, FileAccess.Read,
// following option will let you open
// opened file by other process
FileShare.ReadWrite)){
using(FileStream fs = File.OpenWrite(tmp)){
// this will copy file to tmp
s.CopyTo(fs);
}
}
// upload tmp file...
your problem is similar to what we faced. In our case we are all connected to a domain directory and the problem was the antivirus installed on our server gives read/write permissions to users (executing exe, installing apps). so you specifically need to give a user the right to execute an app that wants to use another app, in this case office docs.
The problem extended to asp apps using Crystal Reports. hope it helps.