Unable to access file - WebClient.DownloadFile - c#

So I've looked for the answer multiple times, and meddled around with permission stuff to no avail, but this code still won't let me download a file to a specified path.
WebClient client = new WebClient();
client.DownLoadFile("http://dl.dropbox.com/u/(My account)/Installer.jar", #"c:\Games\Name\libs");
client.DownLoadFile("http://dl.dropbox.com/u/(My account)/Name.zip", #"c:\Games\Name");
Always gives me: "Access to the path 'c:\Games\Name\libs' is denied."
Also note, using windows XP SP3.

Hi I tried the above code locally and got the same error "Access is denied":
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile("http://localhost:1929/2.png", #"C:\Z\)
Try specifying the filename at the end of the directory, saves locally no problem when i ran it:
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile("http://localhost:1929/2.png", #"C:\Z\FILENAME.jpg")

The App probably doesn't have the permission to write to that folder. If this is a client app, try to run it as an administrator. Otherwise, change the permissions on 'c:\Games\Name\libs' to full control for everyone.

If the access to there is denied try to run as administrator.
If it doesn't work, navigate to the folder C:\Games\Name\libs, right click it and go to Properties.
Choose the "Security" tab, select at the top list the group of users that will run your program. (Try to use Users (YourName-PC\Users)).
With it selected, click on Edit at the bottom of the list, and at the bottom list select Full control under Allow.

you may use code below to see if you have write permission on folder, if not set the failing rule using setaccesscontrol before downloading
public static bool HaveWritePermissionsForFolder(string path)
{
var rules = Directory.GetAccessControl(Path.GetDirectoryName(Path.GetDirectoryName(path))).GetAccessRules(true, true, typeof(SecurityIdentifier));
bool allowwrite = false;
bool denywrite = false;
foreach (FileSystemAccessRule rule in rules)
{
if (rule.AccessControlType == AccessControlType.Deny &&
(rule.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData &&
(groups.Contains(rule.IdentityReference) || rule.IdentityReference.Value == sidCurrentUser)
)
{
denywrite = true;
}
if (rule.AccessControlType == AccessControlType.Allow &&
(rule.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData &&
(groups.Contains(rule.IdentityReference) || rule.IdentityReference.Value == sidCurrentUser)
)
{
allowwrite = true;
}
}
if (allowwrite && !denywrite)
return true;
return false;
}

Related

Open link in browser from code behind of installed application C#

I have made a winform application. When I run the app in visual studio, following code works to open a link from DataGridView link column.
System.Diagnostics.Process.Start("chrome.exe",
grdRelLinks.Rows[e.RowIndex].Cells[2].Value.ToString());
But when I install the build and try to do the same thing, nothing happens. Is there any other setting that I need to make.
Please help.
If you want to open link link from your DataGridView, you should actually pass url not web browser, ie.:
System.Diagnostics.Process.Start(grdRelLinks.Rows[e.RowIndex].Cells[2].Value.ToString());
It will end up trying to open given url with default browser for OS.
Ofc make sure that link of url from url is properly formatted.
If chrome.exe doesn't work for launching, maybe try shortened one: chrome?
Can you also confirm that Win+R (a.k.a. Run...) and then chrome.exe actually opens up Chrome?
If not, can you check if
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\ contains chrome.exe entry?
If so, maybe url formatting is wrong?
You can open a URL in browser with the following snippets:
Process process = new Process();
process.StartInfo.UseShellExecute = true;
process.StartInfo.FileName = "http://google.com";
process.Start();
or
System.Diagnostics.Process.Start("http://google.com");
In your example, to allow users to launch it from the DataGridView, you should simply define a click event like this:
private void grdRelLinks_CellContentClick(object pSender, DataGridViewCellEventArgs pArgs)
{
if (pArgs.RowIndex > -1 && pArgs.ColumnIndex == 2)
{
string url = grdRelLinks.Rows[pArgs.RowIndex].Cells[pArgs.ColumnIndex].Value.ToString();
if(!string.IsNullOrWhiteSpace(url))
System.Diagnostics.Process.Start(url);
}
}
This worked for me.
private void OnGridViewContentClick(object sender, EventArgs e)
{
string chromeExePath = CheckIfChromeIsInstalled();
if (!string.IsNullOrEmpty(chromeExePath))
{
MessageBox.Show("Yayy Chrome.exe was found !");
//Path is not null:
Process.Start(chromeExePath, "http://www.google.de");//Here you can also enter the URL you get from your GridView
string url = grdRelLinks.Rows[e.RowIndex].Cells[2].Value.ToString();
if(!url.StartsWith("http")
{
url = $"http://{url}";
}
Process.Start(chromeExePath, url);
}
else
{
MessageBox.Show("Chrome.exe not found");
}
}
private string CheckIfChromeIsInstalled()
{
DirectoryInfo programFiles = new DirectoryInfo(Environment.GetEnvironmentVariable("PROGRAMFILES"));//Find your Programs folder
DirectoryInfo[] dirs = programFiles.GetDirectories();
List<FileInfo> files = new List<FileInfo>();
Parallel.ForEach(dirs, (dir) =>
{
files.AddRange(dir.GetFiles("chrome.exe", SearchOption.AllDirectories)); //Search for Chrome.exe
});
//files should only contain 1 entry
//Return path of chrom.exe or null
return (files.Count > 0) ? files[0].FullName : null;
}
NOTE: Starting this in an extra Thread could be useful !
EDIT :
Can you please check if cmd.exe works with start chrome.exe "your URL" ?!

how to check if specific user having access to a shared folder location using C#

We have a scenario in our client project where the client application saves and tries to fetch files from a shared folder location , which is a virtual shared folder. But we have been facing issues with a specific application user id losing access to that shared folder. So we need help in pre advance checking if the access is present for that user id on that shared folder location . So thinking of an application to be developed in C# or vb.net to check for that user access .
the way I believe best to check the permission, is try to access the directory (read/write/list) & catch the UnauthorizedAccessException.
If you want to check permissions, following code should satisfy your need. You need to read Access Rules for the directory.
private bool DirectoryCanListFiles(string folder)
{
bool hasAccess = false;
//Step 1. Get the userName for which, this app domain code has been executing
string executingUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
NTAccount acc = new NTAccount(executingUser);
SecurityIdentifier secId = acc.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
DirectorySecurity dirSec = Directory.GetAccessControl(folder);
//Step 2. Get directory permission details for each user/group
AuthorizationRuleCollection authRules = dirSec.GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (FileSystemAccessRule ar in authRules)
{
if (secId.CompareTo(ar.IdentityReference as SecurityIdentifier) == 0)
{
var fileSystemRights = ar.FileSystemRights;
Console.WriteLine(fileSystemRights);
//Step 3. Check file system rights here, read / write as required
if (fileSystemRights == FileSystemRights.Read ||
fileSystemRights == FileSystemRights.ReadAndExecute ||
fileSystemRights == FileSystemRights.ReadData ||
fileSystemRights == FileSystemRights.ListDirectory)
{
hasAccess = true;
}
}
}
return hasAccess;
}

Check network file permission in .NET

I have to check if user, that login into system and run the application, have a specified permissions on some file.
User that run the application is in "BUILTIN\Administrators" group.
While file is local all going fine. I use that code (adopted version from that answers Checking for directory and file write permissions in .NET):
private static bool HasPermission(FileSystemRights permission, AuthorizationRuleCollection accessRules )
{
var allow = false;
var inheritedDeny = false;
var inheritedAllow = false;
if (accessRules == null)
return false;
var currentUser = WindowsIdentity.GetCurrent();
var currentPrincipal = new WindowsPrincipal(currentUser);
foreach (FileSystemAccessRule rule in accessRules)
{
if ((permission & rule.FileSystemRights) != permission)
continue;
if (!currentPrincipal.IsInRole(rule.IdentityReference.Value))
{
continue;
}
if (rule.AccessControlType == AccessControlType.Allow)
{
if (rule.IsInherited)
inheritedAllow = true;
else
allow = true;
}
else if (rule.AccessControlType == AccessControlType.Deny)
{
if (!rule.IsInherited)
return false;
inheritedDeny = true;
}
}
var combined = allow || (inheritedAllow && !inheritedDeny);
return combined;
}
But when I try to check permissions on network shared file I have issue.
For example file shared with FullControl access rule for remote computer user, that remote user also in "BUILTIN/Administrators" group. For "Everyone" group user it is ReadOnly file.
So when I check this with my current, local, log in user by using that code:
if (!currentPrincipal.IsInRole(rule.IdentityReference.Value))
{
continue;
}
I do not go inside of IF condition due my log-in user also in "BUILTIN/Administrators" group.
So code returns TRUE, but in real life I have no write access to that file.
How do can I distinct local and remote Administrator's group users?
PS: I do not want to use exceptions to check accessibility, this will be the "last hope code"

what is the best way to check in C# .NET if a directory has access to list files or a unauthorized access exception would rise

how would I check in the best way in .NET 2.0 C# if I have access to a specified directory
for listing top directory files e.g. a system directory or system volume information folder etc.
My code for it looks now like this, but I think it is not the best way to check for it since it produces an exception each time which is handled by the check function and returning based on it a result.
I would like to use a function which doesn't throw an error to check if in the specified directory is access to list files or maybe my code can be improved or optimized. I might have to check through a thousand directories if exists an access or not. Raising thousand exceptions might cause a problem, but I don't know.
//here my code using System.IO;
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(DirectoryCanListFiles("C:\\Windows\\Prefetch").ToString());
}
public static bool DirectoryCanListFiles(string DirectoryPath)
{
try
{
Directory.GetFiles(DirectoryPath, "*", SearchOption.TopDirectoryOnly);
}
catch { return false; }
return true;
}
The best way to check the permission, is try to access the direcoty (read/write/list) & catch the UnauthorizedAccessException.
However for some reason out there, if you want to check permissions, following code should satisfy your need.
You need to read Access Rules for the directory.
private bool DirectoryCanListFiles(string folder)
{
bool hasAccess = false;
//Step 1. Get the userName for which, this app domain code has been executing
string executingUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
NTAccount acc = new NTAccount(executingUser);
SecurityIdentifier secId = acc.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
DirectorySecurity dirSec = Directory.GetAccessControl(folder);
//Step 2. Get directory permission details for each user/group
AuthorizationRuleCollection authRules = dirSec.GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (FileSystemAccessRule ar in authRules)
{
if (secId.CompareTo(ar.IdentityReference as SecurityIdentifier) == 0)
{
var fileSystemRights = ar.FileSystemRights;
Console.WriteLine(fileSystemRights);
//Step 3. Check file system rights here, read / write as required
if (fileSystemRights == FileSystemRights.Read ||
fileSystemRights == FileSystemRights.ReadAndExecute ||
fileSystemRights == FileSystemRights.ReadData ||
fileSystemRights == FileSystemRights.ListDirectory)
{
hasAccess = true;
}
}
}
return hasAccess;
}

Checking for shared folder write access for current user

I have following method to check current user have write access to given network location
DirectorySecurity shareSecurity = new DirectoryInfo(this.GetFileServerRootPath).GetAccessControl();
foreach (FileSystemAccessRule fsRule in shareSecurity.GetAccessRules(true, true, typeof(NTAccount)))
{
// check write permission for current user
if (AccessControlType.Allow == fsRule.AccessControlType &&
FileSystemRights.Write == (fsRule.FileSystemRights & FileSystemRights.Write))
{
if (null != fsRule.IdentityReference &&
fsRule.IdentityReference.Value == WindowsIdentity.GetCurrent().Name)
{
return true;
}
}
}
return false;
but problem is when folder permission given to user group, above method is failed.
I don't want to check the permissions by writing a file and decide the write access permissions.
is there any way to find current user in the IdentityReference.Value? or suggestions to overcome this issue?
This may work for you:
FileIOPermission writePermission = new FileIOPermission(FileIOPermissionAccess.Write, this.GetFileServerRootPath);
try
{
writePermission.Demand();
return true;
}
catch (SecurityException s)
{
return false;
}
Just curious - why not just try/catch your write operation?
May be you should use DirectoryInfo on that directory to get its security policies.

Categories