C
C#2y ago
VeQox

UnauthorizedAccessException [Answered]

So im trying to change a folders icon, setting it manually sometimes removes it again 🤷‍♂️ , so i hope this works for the time beeing.
34 Replies
VeQox
VeQox2y ago
class Program
{
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern void SHChangeNotify(
int wEventId, int uFlags, IntPtr dwItem1, IntPtr dwItem2);

static void Main(string[] args)
{
const string iconFolder = "icons";

string workingDiretory = Directory.GetCurrentDirectory();
string[] folders = Directory.GetDirectories(workingDiretory);
string[] icons = Directory.GetFiles(Path.Combine(workingDiretory, iconFolder));

for (int i = 0; i < folders.Length && folders[i] != "icons"; i++)
{
string folderPath = folders[i];
string iconPath = icons[i];
string iconName = Path.GetFileName(iconPath);
string desktopIniPath = Path.Combine(folderPath, "desktop.ini");
string hiddenPath = Path.Combine(folderPath, ".hidden");

string[] desktopIniContent = new string[]
{
"[.ShellClassInfo]",
$"IconResource={iconName},0",
"[ViewState]",
"Mode=",
"Vid=",
"FolderType=Generic"
};

string[] hiddenConent = new string[]
{
"desktop.ini",
iconName
};

File.WriteAllLines(Path.Join(folderPath,"desktop.ini"), desktopIniContent, Encoding.UTF8);
File.Copy(iconPath, Path.Join(folderPath, iconName));
File.WriteAllLines(Path.Join(folderPath, ".hidden"), hiddenConent, Encoding.UTF8);


class Program
{
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern void SHChangeNotify(
int wEventId, int uFlags, IntPtr dwItem1, IntPtr dwItem2);

static void Main(string[] args)
{
const string iconFolder = "icons";

string workingDiretory = Directory.GetCurrentDirectory();
string[] folders = Directory.GetDirectories(workingDiretory);
string[] icons = Directory.GetFiles(Path.Combine(workingDiretory, iconFolder));

for (int i = 0; i < folders.Length && folders[i] != "icons"; i++)
{
string folderPath = folders[i];
string iconPath = icons[i];
string iconName = Path.GetFileName(iconPath);
string desktopIniPath = Path.Combine(folderPath, "desktop.ini");
string hiddenPath = Path.Combine(folderPath, ".hidden");

string[] desktopIniContent = new string[]
{
"[.ShellClassInfo]",
$"IconResource={iconName},0",
"[ViewState]",
"Mode=",
"Vid=",
"FolderType=Generic"
};

string[] hiddenConent = new string[]
{
"desktop.ini",
iconName
};

File.WriteAllLines(Path.Join(folderPath,"desktop.ini"), desktopIniContent, Encoding.UTF8);
File.Copy(iconPath, Path.Join(folderPath, iconName));
File.WriteAllLines(Path.Join(folderPath, ".hidden"), hiddenConent, Encoding.UTF8);


File.SetAttributes(desktopIniPath,
File.GetAttributes(desktopIniPath)
| FileAttributes.Hidden
| FileAttributes.ReadOnly);
File.SetAttributes(iconPath,
File.GetAttributes(iconPath)
| FileAttributes.Hidden
| FileAttributes.ReadOnly);
File.SetAttributes(hiddenPath,
File.GetAttributes(hiddenPath)
| FileAttributes.Hidden
| FileAttributes.ReadOnly);
File.SetAttributes(folderPath,
File.GetAttributes(folderPath)
| FileAttributes.ReadOnly);

SHChangeNotify(0x08000000, 0x0000, (IntPtr)null, (IntPtr)null);
}


}
}
File.SetAttributes(desktopIniPath,
File.GetAttributes(desktopIniPath)
| FileAttributes.Hidden
| FileAttributes.ReadOnly);
File.SetAttributes(iconPath,
File.GetAttributes(iconPath)
| FileAttributes.Hidden
| FileAttributes.ReadOnly);
File.SetAttributes(hiddenPath,
File.GetAttributes(hiddenPath)
| FileAttributes.Hidden
| FileAttributes.ReadOnly);
File.SetAttributes(folderPath,
File.GetAttributes(folderPath)
| FileAttributes.ReadOnly);

SHChangeNotify(0x08000000, 0x0000, (IntPtr)null, (IntPtr)null);
}


}
}
im getting a UnauthorizedAccessException but i dont know why
Unhandled exception. System.UnauthorizedAccessException: Access to the path '....\desktop.ini' is denied.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
at System.IO.StreamWriter.ValidateArgsAndOpenPath(String path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.File.WriteAllLines(String path, IEnumerable`1 contents, Encoding encoding)
at SetFolderIcon.Program.Main(String[] args) in
Program.cs:line 46
Unhandled exception. System.UnauthorizedAccessException: Access to the path '....\desktop.ini' is denied.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
at System.IO.StreamWriter.ValidateArgsAndOpenPath(String path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.File.WriteAllLines(String path, IEnumerable`1 contents, Encoding encoding)
at SetFolderIcon.Program.Main(String[] args) in
Program.cs:line 46
File.WriteAllLines(Path.Join(folderPath,"desktop.ini"), desktopIniContent,Encoding.UTF8);
File.WriteAllLines(Path.Join(folderPath,"desktop.ini"), desktopIniContent,Encoding.UTF8);
this throwes the error but how does it not have access if the file doesnt even exist?
RazorSharpFang
The application may not have write access to the folder itself
UnauthorizedAccessException path specified a file that is read-only. -or- path specified a file that is hidden. -or- This operation is not supported on the current platform. -or- path is a directory. -or- The caller does not have the required permission.
VeQox
VeQox2y ago
well how do i check if my program has write access to the folder Hmm
RazorSharpFang
Try out DirectoryInfo of the target directory Check its Attributes property which is of type FileSystemInfo
VeQox
VeQox2y ago
VeQox
VeQox2y ago
Hmm like thats the issue
RazorSharpFang
If this solves your issue, close the post by using command /close
VeQox
VeQox2y ago
well kinda, im just trying to figure it out how to change that without having to go through every folder
RazorSharpFang
Change its attributes so you can write to it?
VeQox
VeQox2y ago
like this?
RazorSharpFang
Uhm, no?
Normal 128
The file is a standard file that has no special attributes. This attribute is valid only if it is used alone. Normal is supported on Windows, Linux, and macOS.
That's not a file
VeQox
VeQox2y ago
HmmNoted ...... right
RazorSharpFang
You want Directory and without readonly
VeQox
VeQox2y ago
DirectoryInfo awd = new(folderPath)
{
Attributes = FileAttributes.Directory
};
DirectoryInfo awd = new(folderPath)
{
Attributes = FileAttributes.Directory
};
RazorSharpFang
Probably best to separate out that declaration and assignment with a try-catch sector Because you may not succeeed changing its attributes
VeQox
VeQox2y ago
HmmNoted the attribute changed from ReadOnly, Directory to Directory it still throws an error tho
RazorSharpFang
Does it still say ReadOnly after you refresh it?
VeQox
VeQox2y ago
in the explorer?
RazorSharpFang
No, call the Refresh() method
VeQox
VeQox2y ago
Nope only directory whats weird is that in the explorer interface it says its readonly
RazorSharpFang
Is it still readonly if you run the app again? What if you tried something like the following
DirectoryInfo directory = new DirectoryInfo(@"C:\my\directory");
DirectorySecurity security = directory.GetAccessControl();

security.AddAccessRule(new FileSystemAccessRule(@"MYDOMAIN\JohnDoe",
FileSystemRights.Modify,
AccessControlType.Deny));

directory.SetAccessControl(security);
DirectoryInfo directory = new DirectoryInfo(@"C:\my\directory");
DirectorySecurity security = directory.GetAccessControl();

security.AddAccessRule(new FileSystemAccessRule(@"MYDOMAIN\JohnDoe",
FileSystemRights.Modify,
AccessControlType.Deny));

directory.SetAccessControl(security);
VeQox
VeQox2y ago
whats the identity on the FileSystemAccessRule constructor?
RazorSharpFang
System.Security.AccessControl
VeQox
VeQox2y ago
Hmm so johndoe is the username? and how do i get the domain or do i just let it be empty so @"\user"
RazorSharpFang
If it's a local user it's .\username A domain user would be part of an organization like a workplace
VeQox
VeQox2y ago
HmmNoted to parse the identy my user name is what echo %username% gives me back? tried both, %username% and the name visually on windows
RazorSharpFang
Is this computer part of a domain?
VeQox
VeQox2y ago
sry fell asleep pepecuke
VeQox
VeQox2y ago
found this im guessingf the workgroup is my domain?
VeQox
VeQox2y ago
Also thought of a different approach im creating and editing the files outside and then move them in the problem is there seems to be already a desktop.ini file inside the folder and with hidden items it cant be viewed
VeQox
VeQox2y ago
also got this enabled
VeQox
VeQox2y ago
with dir i can see there is a desktop.ini file
VeQox
VeQox2y ago
when i remove the file with cmd it works
Accord
Accord2y ago
✅ This post has been marked as answered!