I'm working on a project that a series of images that are deposited in one area of memory (say from a memory stick or download), and distributes them out to their respective folders based on the name of the image - which should correspond with the names of the files in their respective folder.
I have the first few functions of the code written to make this happen and decided to test it by altering the code so that it would carry out the process on a collection of the files in the My Pictures folder.
What should have happened is that each file in the folder was copied to a folder in AppData called 'New Images', and added into the appropriate sub-directory or create the subdirectory if necessary.
This threw up an error stating that access to C:\Users\mark although it did not explain why or what to do about it.
I thought this might be a problem with accessing the My Pictures folder so I copied the images into a folder called 'Test Images' inside the AppData folder (so the program would now be just transferring files between two folders in AppData). The same error occurred and I don't really know what to do next, I have written and read from files in AppData many times before and never encountered this problem. I have also read various entries related to this on this forum but don't seem to be able to get a definitive answer in terms of what to do next!
The code that causes the exception can be seen below:
//main folder (Contains sub-folders for each patient)
string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\New Images";
//variables for sub-directories cannot be given at this point as they are created using a part of the image name
string subDirectory;
//string subDirectory = Path.Combine(rootDirectory, imageName.Split('_')[0]);
string imageName;
//string imageName = Path.GetFileName(image)
string shortcutDirectory;
//string shortcutDirectory = My Documents + Subfolder name + file name
//list to hold all strings as bitmap image
List<Bitmap> images = new List<Bitmap>();
public void createDirectory()
{
//create filing construct for all files passed in from machines
//if main folder does not exist in AppData
if (!Directory.Exists(rootDirectory))
{
//create it
Directory.CreateDirectory(rootDirectory);
}
}
public void saveLatestImages()
{
//specific path for My Pictures only
string testImagesPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Test Images";
//if there is a Pictures folder
if (Directory.Exists(testImagesPath))
{
//get number of files in folder
int fileCount = Directory.GetFiles(testImagesPath).Count();
//more than one file in folder
if (fileCount > 0)
{
//create data structures to store file info
//filePaths holds path of each file represented as a string
string[] filePaths = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Test Images");
//for each file in Pictures...
for (int index = 0; index < fileCount; ++index)
{
//get name of image at current index
imageName = filePaths[index];
//separate the part relating to the patient name (everything before (DD/MM/YYYY))
string subSpecifier = imageName.Split('_')[0];
//add to root directory to form subfolder name
subDirectory = Path.Combine(rootDirectory, subSpecifier);
//subdirectory name formulated, check for pre-existing
//subfolder does not exist
if(!Directory.Exists(subDirectory))
{
//create it
Directory.CreateDirectory(subDirectory); //ERROR OCCURS
}
//otherwise, file will be added to existing directory
//take everything from end and folder\file division to get unique filename
string fileName = imageName.Split('\\').Last();
//add this to the existing subDirectory
fileName = Path.Combine(subDirectory, fileName);
//copy the image into the subfolder using this unique filename
File.Copy(imageName, fileName);
//add full filename to list of bitmap images
images.Add(new Bitmap(fileName));
//update the shortcut to the file in the image storage shortcut folder
shortcutDirectory = getShortcut(subSpecifier, fileName);
//delete image at original path (clear folder so images not copied on next load up)
//File.Delete(imageName);
}
}
}
}
Any help in where to look next would be greatly appreciated!
Thanks
Mark
Is this an ASP.net web application ? In that case can you try providing write permission to the IIS_IUSRS account.
The trick to solve this is ASP.net Impersonation .
Do not give full rights and run your app as an admin. Users will then have admin rights and I am sure you would want to avoid that.
For time being give full rights to everyone to your folder and try running your application as an administrator.
If that works then your can change permissions on your folder accordingly. Also make sure that your folder isn't readonly.
Related
I have a question regarding including a file after it has been copied to the program debug directory.
I have a WPF data grid and in this data grid I display a list of staff with the columns name, age and photo. I can double click a row to open up a new window to update the details and this includes the photo.
In my project directory, I have these folders which I have included in my project. The default folder consists of .jpg files of default staff member photos and the userData folder will be used to store user uploaded photos.
In my .csproj file I have included this:
<ItemGroup>
<Content Include="img\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
This ensures that the img folder gets copied to the output directory upon build. I have also added a .txt file in the userData folder as otherwise it does not copy the folder.
When the user uploads the photo and hits save in my program, it does two things:
Copies the file from source to the output directory of relative path img\userData\filename.jpg
Updates the SQLite record for that staff member's photo path, e.g. From img\default\staffmember1default.jpg to img\userData\newstaffmember1.jpg
My program currently does not update the data grid to reflect changes so upon closing and running the program, it displays a blank photo for the staff member that had the photo change. However, if I was to copy that photo into the included img\userData directory in my project and reload the program it works.
Is there a way to get around this and allow it to display the new photo from the userData directory? Is this whole method suitable or is there a better way of tackling this whole process?
After looking over the link #Clemens this is the solution I have come up with which seems to do the trick.
private void uploadButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if(openFileDialog.ShowDialog() == true)
{
string filepath = openFileDialog.FileName;
string filename = openFileDialog.SafeFileName;
string local_path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string parent_path = local_path + #"\ProjectName";
string child_path = parent_path + #"\user";
if(!System.IO.Directory.Exists(parent_path))
{
System.IO.Directory.CreateDirectory(parent_path);
}
if(!System.IO.Directory.Exists(child_path))
{
System.IO.Directory.CreateDirectory(child_path);
}
string target_path = child_path + #"\" + filename;
File.Copy(filepath, target_path);
photoBox.Source = new BitmapImage(new Uri(target_path));
staff.photo_path = target_path;
}
}
So instead of copying the file to the output directory of the program I decided to do it in the local AppData. The file path also gets stored in the SQLite database and this finds the image fine upon load.
My problem is that I have a windows forms application which is located on a shared location, which is doing some logic and at the end i need to export the data into an excel file.
But the excel file should be exported to the machine that the users is logged in, not on the shared server where the application is hosted ...
Any Ideas?
Example of the situation:
The location of the application is at 192.168.1.150\AppName\App.exe
I have access to this shared location and I'm starting the exe file from there.
I need the application to export an excel file to my computer on my desktop .... how?
If you think the folder "My Documents" is a good place to save the Excel file, then this code will help to get you the path:
var folderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
or if you want to put the file on the Desktop:
var folderPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
The code works regardless of where the folder "My Documents" (or "Desktop") is located for the user (C:, D:, Network share, etc), or which language version his windows installation is using.
To combine with a time based file name:
var fileName = $"your_file_{DateTime.Now:yyMMddHHmmss}.xlsx";
var fullPath = Path.Combine(folderPath, fileName);
I often use time based file names to not overwrite if there is a previous file. (It would of course overwrite if created the same second)
If you want a file name that is guaranteed to be unique you can use a Guid instead of DateTime:
var fileName = $"your_file_{Guid.NewGuid():N}.xlsx";
If the file is just used "within the program" you can also store it in the temporary files folder. To get the path to the temporary files folder you write var folderPath = Path.GetTempPath()
Hope this helps!
Why don't you just use Save File Dialog and save the excel file where you want? Something like this:
private void SaveFile_FileOk(object sender, CancelEventArgs e)
{
string name = SaveFile.FileName;
string[] savearray = new string[] { "some test:" }
File.WriteAllLines(name, savearray);
//this is just an example, your excel file goes here.
}
And on your button to save:
SaveFile.ShowDialog();
You can choose the path for where you want to save...
The program I am writing is a stock inventory system.
So the PC I wrote the program on can locate the files and folders to update on the PC as necessary as the path is valid.
string path = "C:\\Users\\ThisPC\\Documents\\Stock Documents\\Reciepts";
if (!Directory.Exists("C:\\Users\\ThisPC\\Documents\\Stock Documents\\Reciepts"))
{
Directory.CreateDirectory(path);
}
var fileName = #"c:\Users\ThisPC\Documents\Stock Documents\Tyre_File.xml";
This line is also used when I am updating quantities when an order is taken.
So obviously when I run this program in visual studio on another PC this path isn't recognized.
Is there a way that I can add a pointer to create and store my folder and documents in the My Documents on any pc the program loads in?
UPDATE-------------------------------------------------------
string path = "C:\\Users\\ThisPC\\Documents\\Stock Documents\\Customer Reciepts";
if (!Directory.Exists("C:\\Users\\ThisPC\\Documents\\Stock Documents\\Customer Reciepts"))
{
Directory.CreateDirectory(path);
}
This is the only one it wont work for, it creates a folder within a folder when the form is loaded, but your method doesnt work for that?
I believe that
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
is what you are looking for
You want the environment variable for MyDocuments, which will be unique for each user/computer.
String path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
ok, i found this on internet to upload some files.
if (FileUpload1.HasFile)
{
//create the path to save the file to
string fileName = Path.Combine(#"E:\Project\Folders", FileUpload1.FileName);
//save the file to our local path
FileUpload1.SaveAs(fileName);
}
and this
//check to make sure a file is selected
if (FileUpload1.HasFile)
{
//create the path to save the file to
string fileName = Path.Combine(Server.MapPath("~/Files"), FileUpload1.FileName);
//save the file to our local path
FileUpload1.SaveAs(fileName);
}
what is the difference, which one to use? i got confuse. by the way, if i can store file path in database, and next time when i want to delete or see that file, how can i retrieve that? so let say, first i add a record to database and uploaded a .doc file / excel file, next time when i want to edit that record, i want to retrieve the uploaded file, and show it in UI. thanks.
use second one cause it will convert relative or virtual path to real path itself . .u should get path from db and use it to resolve the path the same way you are storing and do manipulation on it delete and etc. for displaying url="~/Files/yourfilename"
yourfilefromdb -u retrieve it from db
string filepath = Path.Combine(Server.MapPath("~/Files"), yourfilefromdb);
File.Delete(filepath);
for showing
if it accessible directly u can just write url="~/Files/yourfilefromdb"
The only difference in two code blocks posted you is in specifying file path.
In case 1, static location is specified to save the file. It can cause problem, if location to save files differ in your production environment. It will require rebuild in that case.
While, in case 2, location is specified using relative path. So, it will always save files at "/Files" location.
//if you already know your folder is: E:\ABC\A then you do not need to use Server.MapPath, this last one is needed if you only have a relative virtual path like ~/ABC/A and you want to know the real path in the disk...
if (FileUpload1.HasFile)
{
string fileName = Path.Combine(#"E:\Project\Folders", FileUpload1.FileName);// they know the right path so .they using directly
FileUpload1.SaveAs(fileName);
}
if (FileUpload1.HasFile)
{
string fileName = Path.Combine(Server.MapPath("~/Files"), FileUpload1.FileName);// i don't know path is correct or not so they using Server.MapPath. . .
FileUpload1.SaveAs(fileName);
}
I'm developing a C# asp.net web application. I'm basically done with it, but I have this little problem. I want to save xml files to the "Users" folder within my project, but if I don't psychically hard code the path "C:......\Users" in my project it wants to save the file in this "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\Users" folder, this is an annoying problem because I can't use the hard coded directory on our web hosts server. Also, I have a checkbox list that populates from the the "DownloadLibrary" folder in my project, and its suppose to download the files from that fold but its also looking to the "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" folder for download even though its populating from the correct folder. I'm very confused by this, its the first time something like this has ever happened to me. Can anyone please help me with this, its the only thing standing in my way to complete this project.
You don't want to use the working directory at all; you want to use a directory relative to where the web application is located (which can be retrieved from HttpRequest.ApplicationPath.
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string pathToApp = request.MapPath(request.ApplicationPath);
string usersPath = System.IO.Path.Combine(pathToApp, "Users");
Update
As VincayC points out; asp.net development is not my strongest skill ;) The above code is essentially equivalent of this (much simpler) code:
string usersPath = HttpRequest.Current.Request.MapPath("~/Users");
If this code appears in the code-behind of a page, you can probably cut HttpContext.Current as well, since the page has a Request property.
That did fix the one problem I'm having, but the downloads are still not downloading from the right place, the program still wants to get the files from "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" directory here is the code I'm using
--Code to populate the checkbox--
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string appPath = request.MapPath(request.ApplicationPath);
string directory = System.IO.Path.Combine(appPath, "DownloadLibrary/");
// Get the list of files into the CheckBoxList
var dirInfo = new DirectoryInfo(directory);
cblFiles.DataSource = dirInfo.GetFiles();
cblFiles.DataBind();
--Download Button Code--
// Tell the browser we're sending a ZIP file!
var downloadFileName = string.Format("Items-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HH_mm_ss"));
Response.ContentType = "application/zip";
Response.AddHeader("Content-Disposition", "filename=" + downloadFileName);
// Zip the contents of the selected files
using (var zip = new ZipFile())
{
// Add the password protection, if specified
/*if (!string.IsNullOrEmpty(txtZIPPassword.Text))
{
zip.Password = txtZIPPassword.Text;
// 'This encryption is weak! Please see http://cheeso.members.winisp.net/DotNetZipHelp/html/24077057-63cb-ac7e-6be5-697fe9ce37d6.htm for more details
zip.Encryption = EncryptionAlgorithm.WinZipAes128;
}*/
// Construct the contents of the README.txt file that will be included in this ZIP
var readMeMessage = string.Format("Your ZIP file {0} contains the following files:{1}{1}", downloadFileName, Environment.NewLine);
// Add the checked files to the ZIP
foreach (ListItem li in cblFiles.Items)
if (li.Selected)
{
// Record the file that was included in readMeMessage
readMeMessage += string.Concat("\t* ", li.Text, Environment.NewLine);
// Now add the file to the ZIP (use a value of "" as the second parameter to put the files in the "root" folder)
zip.AddFile(li.Value, "Your Files");
}
// Add the README.txt file to the ZIP
//zip.AddEntry("README.txt", readMeMessage, Encoding.ASCII);
// Send the contents of the ZIP back to the output stream
zip.Save(Response.OutputStream);</pre></code>
I'm not sure how to get the downloads to point to my application directory,I tried everything I can think off.