Download open file - c#

I want to download Word file with FTP (thanks to webClient object). It's working fine but not in this case :
Users of my company can open this Word files. So, when a user has opened a file the DownloadData command returns an exception :
error 550 : File unavailable (e.g., file not found, no access).
There is a way to download an opened file with FTP ? If not, what can i do ?
Thanks !

This is almost assuredly a poor architecture for whatever project you are working on. You probably want to separate the user editable document store from the downloadable document store. There are many solutions for keeping the two directories in sync when a change is made by a user (dropbox, mesh, or even custom scripts using robocopy and such).

When an Office program opens a file for modification, it intentionally opens it exclusively. As a result, no FTP server is going to be able to open it, unless it uses the backup API. If it uses the backup API, it may well get some intermediate state, since Office may be in the middle of writing something at any time. So no sane person implements an FTP server to use the backup API.

Related

How to open,edit and save a word file stored in the server using ASP .NET MVC

I have a server where word files are stored, i want by pressing a link the user can open the word file from the server, edit in it then saving it back to the server.
till now i figured out that i cant do so directly, but to save the file locally , edit on it then upload it back again.
so is there is a better way to do so? if not how to wait till the file is saved then automatically be uploaded again .
I think your best bet is probably to look into some of the controls out there you can buy to do this. Not necessarily cheap but depends on how much you need this functionality:
https://www.syncfusion.com/aspnet-mvc-ui-controls/word-processor
Regarding detecting a file change locally... you can use the FileSystemWatcher to do this on a folder... this isn't something that will work inherently from a website though. YOu would need to implement and distribute a windows service that your users would install and they would need to download the file they were changing into the folder(s) that your FileSystemWatcher was watching...
https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netframework-4.8
https://learn.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer
Hope this helps.

Get file from Process.Start()-Method

I'm trying to retrieve a file from the Process.Start()-Method.
Following scenario is given:
I obtain a link from a third party program. This link can be a UNC-path, direct link to PDF/JPG/TIF-files, such as "www.certainServer.de/test.pdf", as well as link to programs on the server, which return a special file type, such as "www.certainServer.de/test.aspx".
I open the file like this
Process.Start(_path)
If the link is like "www.certainServer.de/test.aspx" the returned file is automatically downloaded to the deposited download folder.
Is there a opportunity to retrieve the downloaded file or the path to the downloaded file?
The returned Process-object from the Process.Start()-Method doesn't seem to be helpful.
Process.Start does not necessarily download a file. It simply starts a process. You just as easily could start Notepad, which has no side effects (except, of course, what you do with notepad once it's started). If the process you start (in your case, calling a web page) has external effects, the process engine knows nothing about it.
It sounds like you know where the file is supposed to be deposited, so you could use something like a FileSystemWatcher to be alerted when a new file is added (which doesn't necessarily mean it came from your process, though) or get a list of files before and after the process is run.
But there's nothing inherent to System.Process to definitively know what that process did.
Another option might be to call the URL from your code (using WebClient or something similar) and capturing the result (which might be a file, or just a web page, depending on the URL). It's not as general as starting a process and letting the default browser handle the download, but it would capture the results more definitively.

Permanently add a database to an application C#

I'm trying to create software that will add a computer to an Active Directory domain. One criteria I need to meet is the machine must be added to the proper OU. In order to do this I have a set list of site locations with addresses (this is how we determine OU). This list is currently in the form of an ACCDB file, and I want to include this within the application as the Access list will not be changed.
Everything I see wants the DB file to be connected to in a different location such as server or on the local machine. My preference is to use the DB file as a reference or something inside the program's .exe file itself. I may be missing something horribly obvious, but it's been messing with me for a couple days so I'm reaching out for help.
To clarify, this software MUST be self contained (no installer). It must also be able to determine the proper OU to join to the domain (no access to shares until the PC joins the domain). It must also be user-friendly enough to avoid mistakes, meaning I want to avoid copying distributing multiple files that must go to a correct location. This is why I want to embed the ACCDB file into the application for on the fly use.
Things get much easier because this is static data. You don't have to worry about persisting this data, reclaiming changes into your program, or users accidentally deleting something, etc. You will be able to just use an embedded resource in your application. In the link, follow the examples using the image file. Text file examples will corrupt your database.
However, there is still a trick to doing this. The problem is the Access engine included with Windows will not be able to open the database as a resource, and so you will need to save this file to the local hard drive. The good news is its not as bad as it seems, because your program can do this as needed, and make sure it's right, rather than asking the user to put a file in a specific place.
As for where to put the file when you extract it... the safest and best place is the Application Data folder. You can easily get the path for this folder by checking the results of this call:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
This will give you a path where standard privilege users do have write access, no matter which user.
In summary:
Embed the ACCDB as a resource.
When your program runs, get the Application Data path using the Environment object.
Open a FileStream for writing to a file based on the path from #2
Open the embedded resource as a Stream object in C#
Copy the stream from #4 to the stream from #3. Make sure to use a mechanism intended for binary data, rather than text.
Close/Dispose your streams, so no locks remain on the file. This is as simple as putting using blocks in the right places.
Open a normal Access connection to the file you just made, using any of the thousands of tutorials or examples available on the web as a guide.
In this way, you only need to distribute the final .exe file, and users won't need any special permissions to use the database. You don't have to worry if a user deletes your file; it's still embedded in the application, which will recreate it if needed every time it starts up.
The downside is a clever user may be able to manipulate the database to end up in an undesirable OU. If you need to worry about this, you should consider having the program check a web service, rather than using embedded data. Anything you embed can ultimately be altered by an end user. A web service is also nice because you can update your mapping data as your organization evolves, without needing to rebuild or redistribute the program.

Get username of user who has file open on network drive - Microsoft Office Style

I would like to add user friendly file locking to a software running under Windows (Windows 7 mostly), written in C#.
I already achieved the file locking part, by keeping the files in use "open" in the corresponding process. What I now still would like to add is recognition of the user who has a file currently open/locked.
The files being accessed lie on a mapped network drive, used by different users on different computers.
When a file is locked and a second person tries to open the file, he should be confronted with a dialog, similar to the "File in use"-dialog from the Microsoft Office programs. There, also the name of the user, currently editing the file, is displayed.
I found solutions to find out the processes, which have a certain file open (used this one: How do I find out which process is locking a file using .NET?)
and I'm also able to read the name of the user who created this process out of it. However, when opening a locked file on a network drive, the username yielded by doing it like this, is always my own one, instead of the one from the user locking the file.
Does anyone have an idea how one could achieve this? I mean Microsoft Office somehow can do this on my same PC with the same user permissions, too. I just'd like to know how...
Cheers!
Office uses a very simple technique, I'll talk about it in .NET terms. Whenever an Office app opens a document file, using FileShare.None, it also creates a hidden "lock-file" with a name that's based on the document file (say, with ".lockfile" appended). And writes Environment.UserDomainName into that file. The file is created with FileOptions.DeleteOnClose and FileShare.Read and kept open as long as the document file is open.
It closes the lock-file when the document is closed again. Using FileOptions.DeleteOnClose ensures that the lock-file disappears even when the program bombs.
When opening the file produces a locking violation, it goes looking for the lock-file and reads the user name. Easy peasy, simple to implement yourself. But can of course only work if it is one particular app that opens the file.

How loop thru all files in dir on CLIENT's computer?

I have an asp.net page that allows a user to select an excel file on his computer and then (1) upload it to the server, and (2) import into a SQL server table. This works fine.
Now I want to enhance the pages functionality to allow the user to select a directory on his computer and then automatically upload/import EACH file (Only of types xls, xlsx) in the clients directory. How can I do this? (Alternatively the user can select a file and then check a checkbox that says "upload all files in this directory", then it will process each file, etc.)
I found a way to loop thru the directory on the server side. But I can't figure it out for client side. Thanks!
You can't. Or at least, you shouldn't be able to.
A properly written browser specifically prevents direct access to the file system of the computer it is running on as a security precaution. The only "correct" way to access a file on a remote machine is to use the browser's File Upload form control on the page and have the user specify the file (or files) they want to send you.
Basically, no.
Many advances have been made in browser security to stop people doing this sort of thing.
The main solution is to use some kind of local plugin that gives this sort of access, but as this can be used for many nefarious deeds, it's very much frowned upon now.
You can of course let the user choose many files, there are various methods for doing this - but you can't automate it by the browser.
What's to stop someone searching for 'creditscards.txt' and uploading it without the user being aware?
One way I can think of is a Java applet. This is executed locally and has full access to the computer and the browser. They are being shut down for similar reason: it's just not safe.
I have outlined a way, but I must emphasize that this must be avoided. It's not because you can that you should.

Categories