C# - Read local download path on file download - c#

For a c# web application, we would like to create the possibility to download a file. If User 1 downloads file MyFileToDownload.txt, we would like to show the local saving directory on our website. For instance if he downloads MyFileToDownload.txt we want to show a message like: "File MyFileToDownload.txt is locked by User 1 in directory 'Downloads'".
So my question now: Is it possible to read the local saving location from a user? Or is the File anyway always saved in the directory Downloads on the most common operating systems such like "Windows and MacOs"
Our File download Code:
Response.ContentType = "text/html";
Response.AppendHeader("Content-Disposition", "attachment; filename=MyFileToDownload.txt");
Response.TransmitFile(#"C:\Users\Administrator\MyFileToDownload.txt");
Response.End();

The browser won't supply that information to you as it would represent a security risk to the user.
Whilst there are default download locations (on most recent version of Windows it's the Downloads folder in the user folder, for instance), all browsers allow users to choose another location should they wish to.

Related

Automatically uploading a file to Google Drive File Stream with a Windows Service

I have made a Windows service that;
Downloads a CSV file from a regularly updated internal database through a WebClient every hour.
Put that CSV file into a designated folder.
In the original test case, it was put into a local folder on my desktop (C:).
The test case worked perfectly.
The CSV would replace the old file with the newly downloaded one with the same name.
As listed above. This works perfectly on a local folder. However, we intend for it to work through Google Drive File Stream. As we have a Google Sheet that manipulates and sought the data for us for any CSV file that is under the given name.
This is the current method of downloading and placing the file.
public void CSVDownload()
{
string url = #"YOUR_CSV_URL_HERE";
WebClient client = new WebClient();
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(url), #"YOUR_GOOGLE_DRIVE_FILE_STREAM_FOLDER_HERE\NAME.csv");
void client_DownloadFileCompleted(object CSVDownload, AsyncCompletedEventArgs e)
{
eventLog1.WriteEntry("CSV File (NAME.csv) downloaded");
}
}
My question is why can't I currently automatically upload a file to Google Drive File Stream through a Windows Service? Is it because Google Drive File Stream requires certain permissions or actions? Is it because the drive is "virtual" and not physical (H:)? Below is the folder I am trying to upload to in Google Drive File Stream (H:\My Drive\Test).
The code also runs through completely as the log files show that the methods are used. However, there seems to be some block between the download and placing of the CSV file in a Google Drive File Stream folder.
Update: There has been little progress so far. One of my colleagues maybe suggests that there needs to be some sought of user permission to push. Like a username and password. If this is true does anyone know how I could achieve this?
Update #2: In the 'Registry Editor' I found some interesting info.
Press Windows + R
Type regedit.exe
HKEY_CURRENT_USER -> SOFTWARE -> Google -> DriveFS -> Share
As you can see there are two values. 'MountPoint = H' is obviously the drive letter it is mapped to and 'ShellIpcPath = \\.\Pipe\GoogleDriveFSPipe_user.name_shell' which might be useful. I played around with ShellcpPath but to no prevail.
Update #3: #Ben Voigt mentioned to use DriveInfo.GetDrives() to see if the drive is found by the service. I run the code and it looks like it does exist.
Here is what the console spit out:
Drive H:\
Drive type: Fixed
Volume label: Google Drive File Stream
File system: FAT32
Available space to current user: 15987068928 bytes
Total available space: 15987068928 bytes
Total size of drive: 16106127360 bytes
As you can see it exists however it uses File system: FAT32 instead of File system: NTFS which all my other drives use (C:),(D:),etc. So it seems that only Google Drive File Stream uses FAT32.
Test Case:
Works perfectly when placing the CSV files into a local folder.
client.DownloadFileAsync(new Uri(url), #"C:\Users\user.name\Desktop\Test\designtasks.csv");
client.DownloadFileAsync(new Uri(url), #"C:\Users\user.name\Desktop\Test\designjobs.csv");
Does not work when placing into a Google Drive File Stream folder.
client.DownloadFileAsync(new Uri(url), #"H:\My Drive\Test\designtasks.csv");
client.DownloadFileAsync(new Uri(url), #"H:\My Drive\Test\designjobs.csv");
To clarify about the test case. I am actually getting two CSV files. However, the code is basically the same. So I only mention getting one in my original question to keep it cleaner and more straightforward.
I found the solution! It might not be optimal for all cases however it works in my case.
Here is what I did;
Make a project installer with InstallerProjects.vsiz. Obviously, if you are using a different version of VS, this might change. Some of the older version already come with it installed and the newer versions do not automatically include it. You will have to also find the correlating version as the one linked is for VS2017. Here is a tutorial on how to implement an installer on a windows service.
Once you have implemented the installer, right click on serviceProcessInstaller1 (or whatever you decided to call it) and select properties.
In the properties window, look a for the 'Account' field and set it to 'User'.
Save and build you project. That's it.
What does's this actually do? In plain English; It basically makes the service impersonate a user so it can read and write files on the system.
When installing on a different computer from which the service was built on, 'Windows Defender Shield' will block the service from installing. This is just Windows bring cautious. Obviously, if you built the service without ill intent this will not harm your computer.
To continue installation click "More info" on the 'Windows Defender Shield' screen and click "Run anyway".
Before the Service finishes installing, it will stall and ask for user information. In most use cases, giving it your own user information ill suffice.
If you are a user on a domain or anything along those lines. You will need to add the domain prefix to the 'Username' field. Example: DOMAIN\user.name.

C# ASP.NET Retrieving file address in string

I am building a method that will build an XLS file and uploading it on user's computer.
I am using this guide:
http://csharp.net-informations.com/excel/csharp-create-excel.htm
So code that will define my destination address is:
xlWorkBook.SaveAs("C:\\Something\\csharp-Excel.xls", Excel.XlFileFormat.xlWorkbookNormal);
Now it is default, but i want to allow user to define it by him self, so as far as i understand, i need an html field, which will open common "browse window" and save file path to string, which will be later used in xlWorkBook.SaveAs function. I have read a bit about FileUpload, but i don't really sure that it is what i am looking for.
The code that you have there will save the file on the web server itself, not on the user's computer. You'll need to stream the file down to the user via the browser, and then they will be able to choose where to save it.
You could save the file on the server and then stream it to the user using Response.WriteFile, or you could stream it from memory if you don't want to keep a copy of the file on the server.
This code will create a file on the server, not on the users/clients computer. If you want the user to be able to download the file to his/her computer and select the location where the file is stored, you need to create a file (.aspx file or controller method, depending on wether you are using webforms or MVC) and have it stream the file to the user's browser. The browser will then take care of displaying the "Save as" dialog where the user can select the destination location.

To browse folder and Create folder in the server and upload files using asp.net

I am Currently working on asp.net i have worked on file upload by uploading files but i want browse a folder not a file and get all files in it and get foldername and create foldername in server and upload files it to server.Pls give me some refernce and help me to do this.
My aim is when i browse that folder all it files present in it should upload .Only files should upload not folder
Note:To browse folder not file.
Actually you are supposed to include a question if you want an answer, but it seems you are completely new to this so here are a few things you should know when it comes to asp.net and folder/file handling:
Your virtual path always corresponds to a local path on your webserver. Since it would be bad to hardcode that you might want to start off by mapping it. (e.g. /uploads/ to _C:\intepub\application\uploads)
"and get foldername"
string localpath = Server.MapPath("/uploads");
"and create foldername in server"
next you can check if that folder already exists, or if not - create it.
if(!System.IO.Directory.Exists(localpath))
System.IO.Directory.Create(localpath))
Keep in Mind though that your IIS-User needs the rights to create new directories
Now that you have made sure that your upload directory exists, you can upload/download files. Here is a good tutorial to get started:
"and upload files it to server"
http://msdn.microsoft.com/en-us/library/aa479405.aspx
"but i want browse a folder not a file and get all files in"
You can do that on the server, not the client. Your asp.net code never executes on the client.
string[] filenames = System.IO.Directory.GetFiles(localpath);
"My aim is when i browse that folder all it files present in it should upload"
That one isn't so easy, sorry. It would pose a serious security risk to users.
Maybe this will point you in the right direction (apparently it works with Chrome)
How do I use Google Chrome 11's Upload Folder feature in my own code?
When it comes to files, directories, filepaths, etc. in general, I would recommend taking a closer look at these classes:
System.IO.File
System.IO.Directory
System.IO.Path

FTP transfer via ASP.net page

I'm rather new to development and I have a problem which I haven't sound a solution for. I can't seem to find if it is possible or not to solve, anyway..
I want to create an asp page which would allow a user to download a whole folder from an ftp server. The ftp server itself is not on the same physical server as the asp site. To further complicate the issue is that I want to use either explicit or implicit transfer which I can't seem to work in a browser.
The webpage acts as an intermediary between the client and the ftp server, and is meant to be as user friendly as possible. eg. the user just have to press download and it automatically downloads from the ftp server without the use of an installed local client.
client -> asp page -> ftp server
client <- ftp server
My problem is that the asp page does not have the permission to create files on the client system. I have managed to connect to the ftp and try to download all files in a folder but the files do not appear on the client in the target folder.
I might just be searching for the wrong terms but I would appreciate any feedback.
when you say "client" I assume you are referring to the asp.net server. In that case you need to check what user the app pool for your website is running under. Then you need to make sure that user has write permissions to the folder you are storing the ftp files in.
The user is most likely network service.
Your ASP site will not be able to write directly to the end user's system. Just think, would you want any website to have direct access to your file system?
You could download the files to a temporary folder on the Web Server, and then use write it in a response to prompt the user to download it.
Here is a SO question regarding downloading files in ASP.NET
From our question's comment discussion, looks like you are looking to provide user with a option to download file which you have collected on server side from ftp server
//Connect to your file
FileStream sourceFile = new FileStream(Server.MapPath(#"FileName"), FileMode.Open);
float FileSize= sourceFile.Length;
//Write the file content to a byte Array
byte[] getContent = new byte[(int)FileSize];
sourceFile.Read(getContent, 0, (int)sourceFile.Length);
sourceFile.Close();
//Build HTTP Response object
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", getContent.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.BinaryWrite(getContent);
Response.Flush();
Response.End();
Please see if the above code helps.
Also, check out HTTP Response file Attachment Discussion

Providing links to files outside of IIS

I have an upload function in my system that stores the files on the d drive e.g D:\KBFiles. Now i need to offer these files as links through internet explorer. Obviously i cant just offer a path e.g D:\KBFiles\test.pdf. Whats the best way to handle this scenario
Write "proxy" file with such code and call it DownloadFile.aspx:
string fileName = Request.QueryString["file"];
string filePath = Path.Combime("D:\\KBFile", fileName);
Response.WriteFile(filePath);
Then have such link:
test.pdf
This allows you to check the user permissions if you're using Login system and also you can check the requested file against some white list to prevent hacking attempts.
You need to create a Virtual Folder for that windows folder inside your WebApplication. As soon as IIS has mapped the virtual folder, it would be possible to use direct links, which would have your WebApplication as a root.

Categories