Repository navigation
Expand file tree
/
Copy pathProgram.cs
More file actions
159 lines (134 loc) · 4.98 KB
/
Copy pathProgram.cs
File metadata and controls
159 lines (134 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
namespace FolderStatus;
using System;
using System.IO;
using System.Runtime.InteropServices;
internal class Program
{
private const uint FCS_FORCEWRITE = 0x00000002; // Forces an immediate shell refresh
private const uint FCSM_ICONFILE = 0x00000010; // Tells Windows we are changing the icon
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHFOLDERCUSTOMSETTINGS
{
public uint dwSize;
public uint dwMask;
public IntPtr pvid;
public string pszWebViewTemplate;
public uint cchWebViewTemplate;
public string pszWebViewTemplateVersion;
public string pszInfoTip;
public uint cchInfoTip;
public IntPtr pclsid;
public uint dwFlags;
public string? pszIconFile; // Maps to fcs.pszIconFile
public uint cchIconFile; // Maps to fcs.cchIconFile
public int iIconIndex; // Maps to fcs.iIconIndex
public string pszLogo;
public uint cchLogo;
}
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int SHGetSetFolderCustomSettings(ref SHFOLDERCUSTOMSETTINGS pfs,string pszPath, uint dwReadWrite);
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Missing parameters");
Log("Missing parameters");
return;
}
string action = args[0].ToLowerInvariant().Trim();
string folderPath = args[1];
if (!Directory.Exists(folderPath))
{
Console.WriteLine("Folder does not exist");
Log("Folder does not exist");
return;
}
try
{
ProcessFolderStatus(action, folderPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Log(ex.Message);
}
}
static void ProcessFolderStatus(string action, string folderPath)
{
switch (action)
{
case "done":
WriteAndRefreshIcon(folderPath, @"C:\Program Files\FolderStatus\status\Completed.ico");
break;
case "progress":
WriteAndRefreshIcon(folderPath, @"C:\Program Files\FolderStatus\status\InProgress.ico");
break;
case "restore":
WriteAndRefreshIcon(folderPath, null);
break;
default:
Console.WriteLine("Invalid action");
Log("Invalid action");
return;
}
Log("Successfully applied folder status");
}
static void WriteAndRefreshIcon(string folderPath, string? iconPath, int iconIndex=0)
{
SHFOLDERCUSTOMSETTINGS fcs = new SHFOLDERCUSTOMSETTINGS();
// fcs.dwSize = sizeof(SHFOLDERCUSTOMSETTINGS);
fcs.dwSize = (uint)Marshal.SizeOf(typeof(SHFOLDERCUSTOMSETTINGS));
// fcs.dwMask = FCSM_ICONFILE;
fcs.dwMask = FCSM_ICONFILE;
// fcs.pszIconFile = iconPath;
fcs.pszIconFile = iconPath;
// fcs.cchIconFile = 0;
fcs.cchIconFile = 0;
// fcs.iIconIndex = iconIndex;
fcs.iIconIndex = iconIndex;
// SHGetSetFolderCustomSettings(&fcs, folderPath, FCS_FORCEWRITE);
// In C#, passing by 'ref' automatically passes the memory address (&fcs)
int hResult = SHGetSetFolderCustomSettings(ref fcs, folderPath, FCS_FORCEWRITE);
if (hResult != 0)
{
Console.WriteLine("Failed to refresh folder status");
Log("Failed to refresh folder status");
}
}
static void WriteCustomIcon(string iniPath, string iconPath)
{
if (File.Exists(iniPath))
{
File.SetAttributes(iniPath, FileAttributes.Normal);
}
string[] iniLines = new string[]
{
"[.ShellClassInfo]",
$"IconResource={iconPath},0"
};
File.WriteAllLines(iniPath, iniLines);
}
static void ApplyAttributes(string folderPath, string iniPath)
{
// desktop.ini file must be marked as hidden, archive and system file for it to work
File.SetAttributes(iniPath, FileAttributes.Archive | FileAttributes.Hidden | FileAttributes.System);
// the folder with the desktop file must also be read only for some reason?
File.SetAttributes(folderPath, FileAttributes.ReadOnly);
}
static void ResetFolderDefaults(string folderPath, string iniPath)
{
if (File.Exists(iniPath))
{
File.SetAttributes(iniPath, FileAttributes.Normal);
File.Delete(iniPath);
}
DirectoryInfo folderInfo = new DirectoryInfo(folderPath);
folderInfo.Attributes &= ~FileAttributes.ReadOnly;
}
static void Log(string message)
{
string logPath = Path.Combine(Path.GetTempPath(), "FolderStatus.log");
File.AppendAllText(logPath,
$"{DateTime.Now:HH:mm:ss} {message}{Environment.NewLine}");
}
}