I want to delete Read-only Folder. I did like this
//Remove Read-only for the Folder
File.SetAttributes(folderpath, File.GetAttributes(folderpath) & ~FileAttributes.ReadOnly);
//Delete Folder
FileInfo myfileinf = new FileInfo(folderpath);
myfileinf.Delete();
But i get this Error
"Access to the path 'E:\Working Folder\RPEssential\RPEssential\ResourcePlus-PL\RDLReports\t' is denied".
As I commented earlier the problem is that you are trying to delete a folder as you were deleting a file.
You should use Directory.Delete method to delete a folder.
In the following link there is a good example on how to use it
http://msdn.microsoft.com/en-au/library/fxeahc5f(v=vs.100).aspx
public static void Main()
{
// Specify the directories you want to manipulate.
string path = #"c:\MyDir";
string subPath = #"c:\MyDir\temp";
try
{
// Determine whether the directory exists.
if (!Directory.Exists(path))
{
// Create the directory.
Directory.CreateDirectory(path);
}
if (!Directory.Exists(subPath))
{
// Create the directory.
Directory.CreateDirectory(subPath);
}
// This will succeed because subdirectories are being deleted.
Console.WriteLine("I am about to attempt to delete {0}", path);
Directory.Delete(path, true);
Console.WriteLine("The Delete operation was successful.");
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
finally {}
}
There can be many reasons for a read only to be denied. Is the folder in use? Open in a console? Running an executable? All of these things you should check. Even if it has the permission, if the directory is in use, it won't allow you to delete it.
Related
I am trying to delete a file from a server via ASP.NET I am trying to use System.IO.File.Delete like so:
try
{
var filePath = System.Web.HttpContext.Current.Server.MapPath("C:/www/project/Images/" + landingCells.imageBytes);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
}
catch
{
return false;
}
But every time it returns false, I am able to write a file to the server:
try
{
System.IO.File.WriteAllBytes("C:/www/project/Images/" + filePath, bytes);
}
catch
{
return false;
}
But I am unable to delete the file, yes the file path and name are correct are the folder has full control, what am I doing wrong?
This is the error I got:
An error occured: ‘C:/www/project/Images/ANW00012018053015551423458244a89b23-5ed7-42a3-a2fc-4b15a90fb3cf.jpg' is a physical path, but a virtual path was expected.
The reason we use Server.MapPath is we do not want to hard-code the file path inside the code.
try
{
string fileName = "Sample.jpg";
var filePath = Server.MapPath("~/Images/" + fileName); // Do not pass byte array here
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
}
catch
{
// Do not swallow the exception. Instead, log them to persistant storage.
}
First of all very risk approach is hardcoding the path to folder. What if admin will move an app to disk D?
IMHO the issue is here:
var filePath = System.Web.HttpContext.Current.Server.MapPath("C:/www/project/Images/" + landingCells.imageBytes);
You're trying to access a stream so the path is very long and looks more or less like "C:\www\project\Images\0x00a00efe............."(so the path here is very long). Instead of imageBytes property you should use file name.
Also, when you're getting similar issues, catching exception and logging it, is very usefull.
I am trying to copy a preloaded SQLite db into my UWP app. On the initial installation it copies the "test.db", but the size is 0 bytes and there are no tables or data. The original db is 1300 bytes with data and tables.
Another factoid...when I create the app Using Visual Studio 2017 and compile and run/debug the app it works fine, but when I sideload the appx file or download from the Windows Store the db is empty.
Here is the code that I am using:
Task task = CopyDatabase();
private async Task CopyDatabase()
{
bool isDatabaseExisting = false;
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("Express.db");
isDatabaseExisting = true;
}
catch
{
isDatabaseExisting = false;
}
if (!isDatabaseExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("Express.db");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder, "Express.db", NameCollisionOption.ReplaceExisting);
}
}
I'm not getting any error messages.
Does the your database file deployed correctly to the target system?
To confirm it, see your deployed - "Package" - folder. Open command prompt with administrative previleges, and see the directory
c:\Program Files\WindowsApps\your-app-id
If your database file deployed successfully, you can see it in the directory. If not, you may need to change the deploy settings.
To deploy the file to target machine, you should set the property of the one as ...
'BuildAction=Contents'
'Copy to output directory'='Always Copy'
You can set it from solution explorer and right-click the your database file.
If you succeeded the deploying file, your code will copy your database file to app local folder.
c:\Users\YOUR-USER-ID\AppData\Local\Packages\YOUR-APP-ID\LocalState
First, you would need to use await for your CopyDatabase method.
Second, I suggest you call this method in MainPage_Loaded event handler instead of MainPage's Constructor.
public MainPage()
{
this.InitializeComponent();
this.Loaded += MainPage_Loaded;
}
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
gui = this; InitializeComponent();
await CopyDatabase();
DataSetup();
CreateNewChartButton.Visibility = Visibility.Collapsed;
SignInButton_Click(null, null);
}
My folder structure is webapp-->resource--> images.
Here is my code:
public String addProductPost(#ModelAttribute("products") Product product, HttpServletRequest request) {
productDao.addProduct(product);
System.out.println(product);
MultipartFile productImage = product.getProductImage();
String rootDirectory = request.getSession().getServletContext().getRealPath("/");
path = Paths.get(rootDirectory +"webapp/resources/image"+ product.getProductId()+".png");
if (productImage !=null && !productImage.isEmpty()) {
try {
productImage.transferTo(new File(path.toString()));
/*Files.copy(Paths.get(productImage.toString()), path);*/
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Product image saving failed ", e);
}
}
Did you try System.out.println(path); ? If you're not getting any error then the image is getting saved in the said directory but doesn't show up in eclipse project manager. To see the image, navigate to the folder where you have said the image.
I have a dotnet site which contains a virtual directory (/ArticleImages) which maps to a file share on another server. The file share is accessible to a large number of people so, as a security measure, I do not want any asp.net pages to execute in this folder (e.g. putting default.aspx in the file share and browsing to site.com/ArticleImages/default.aspx should either not serve or, preferably, serve as a simple download rather than executing).
I'm using IIS 6.0 and added the virtual directory. If I remove the application from this folder, it uses the parent application and complains that it can't read web.config. If I add an application to this folder, even if I remove all application extensions, it complains that svc-xyzzy (the account used to access the share) doesn't have access to 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files'.
How do I have a sub folder of an application which does not execute dotnet code?
If the file share is readable by the user that your app pool is running under (Network Service by default) you can remove the virtual directory completely and create an ASP.NET application that will stream the files to the browser. If you're using MVC it's simply returning a file result. This has an added benefit in that you will be able to restrict the users from downloading the files. i.e. You can require that a user is logged in or has certain permissions to download the files. Also make sure you test for path traversal, you would not want a user entering ../../filename to download files they are not permitted to.
Option 1: ASP.NET MVC
public ActionResult Download(string file)
{
// Check for directory traversal attack
if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1)
{
return new HttpNotFoundResult();
}
file = System.IO.Path.Combine("\\FILE_SHARE_FOLDER\\", file);
if(!System.IO.File.Exists(file))
{
return new HttpNotFoundResult();
}
return this.File(file, GetMimeType(file));
}
Option 2: Webforms
private void DownloadFile(string file)
{
// Check for directory traversal attack
if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1)
{
Response.StatusCode = 404;
Response.End();
}
file = System.IO.Path.Combine("\\FILE_SHARE_FOLDER\\", file);
if (!System.IO.File.Exists(file))
{
Response.StatusCode = 404;
Response.End();
}
Response.ContentType = GetMimeType(file);
Response.TransmitFile(file);
}
Note You will need a method to get the MIME Types for both MVC and Webforms (MIME Type Method From KodeSharp)
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}
You can check on global.asax for the request, and if is coming from the directories that you not allow, then stop the processing as:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
if(cTheFile.StartsWith("/articleimages", StringComparison.CurrentCultureIgnoreCase)
{
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
HttpContext.Current.Response.Write("Please start from home page");
HttpContext.Current.Response.StatusCode = 403;
HttpContext.Current.Response.End();
return ;
}
}
Of course you can simple place one extra web.config on the directory with this inside:
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
but if they can delete it is not useful as the code.
I have a ASP.NET SOAP web service whose web method creates a PDF file, writes it to the "Download" directory of the applicaton, and returns the URL to the user. Code:
//Create the map images (MapPrinter) and insert them on the PDF (PagePrinter).
MemoryStream mstream = null;
FileStream fs = null;
try
{
//Create the memorystream storing the pdf created.
mstream = pgPrinter.GenerateMapImage();
//Convert the memorystream to an array of bytes.
byte[] byteArray = mstream.ToArray();
//return byteArray;
//Save PDF file to site's Download folder with a unique name.
System.Text.StringBuilder sb = new System.Text.StringBuilder(Global.PhysicalDownloadPath);
sb.Append("\\");
string fileName = Guid.NewGuid().ToString() + ".pdf";
sb.Append(fileName);
string filePath = sb.ToString();
fs = new FileStream(filePath, FileMode.CreateNew);
fs.Write(byteArray, 0, byteArray.Length);
string requestURI = this.Context.Request.Url.AbsoluteUri;
string virtPath = requestURI.Remove(requestURI.IndexOf("Service.asmx")) + "Download/" + fileName;
return virtPath;
}
catch (Exception ex)
{
throw new Exception("An error has occurred creating the map pdf.", ex);
}
finally
{
if (mstream != null) mstream.Close();
if (fs != null) fs.Close();
//Clean up resources
if (pgPrinter != null) pgPrinter.Dispose();
}
Then in the Global.asax file of the web service, I set up a Timer in the Application_Start event listener. In the Timer's ElapsedEvent listener I look for any files in the Download directory that are older than the Timer interval (for testing = 1 min., for deployment ~20 min.) and delete them. Code:
//Interval to check for old files (milliseconds), also set to delete files older than now minus this interval.
private static double deleteTimeInterval;
private static System.Timers.Timer timer;
//Physical path to Download folder. Everything in this folder will be checked for deletion.
public static string PhysicalDownloadPath;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
deleteTimeInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["FileDeleteInterval"]);
//Create timer with interval (milliseconds) whose elapse event will trigger the delete of old files
//in the Download directory.
timer = new System.Timers.Timer(deleteTimeInterval);
timer.Enabled = true;
timer.AutoReset = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
PhysicalDownloadPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Download";
}
private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
//Delete the files older than the time interval in the Download folder.
var folder = new System.IO.DirectoryInfo(PhysicalDownloadPath);
System.IO.FileInfo[] files = folder.GetFiles();
foreach (var file in files)
{
if (file.CreationTime < DateTime.Now.AddMilliseconds(-deleteTimeInterval))
{
string path = PhysicalDownloadPath + "\\" + file.Name;
System.IO.File.Delete(path);
}
}
}
This works perfectly, with one exception. When I publish the web service application to inetpub\wwwroot (Windows 7, IIS7) it does not delete the old files in the Download directory. The app works perfect when I publish to IIS from a physical directory not in wwwroot. Obviously, it seems IIS places some sort of lock on files in the web root. I have tested impersonating an admin user to run the app and it still does not work. Any tips on how to circumvent the lock programmatically when in wwwroot? The client will probably want the app published to the root directory.
Your problem may be related to the fact that IIS reloads the Web Service Application if the directory or files contained in the main folder changes.
Try creating / deleting files in a temporary folder which is outside the root folder of your application (be aware of permissions on the folder to allow IIS to read/write files).
Instead of writing directly to the file system, why not use isolated storage?
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx
This should solve any location or permission based issues that you are having
I forgot to come back and answer my question.
I had to give the IIS_IUSRS group Modify permissions to the directory where I was reading/writing files.
Thanks to all those who answered.