Skip to content

Commit b5dd401

Browse files
committed
Add project files.
1 parent 7052dd4 commit b5dd401

14 files changed

+2304
-0
lines changed

Save In Companion.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.28307.852
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Save In Companion", "Save In Companion\Save In Companion.csproj", "{EAF1312A-B8D9-4021-A2F9-CBB47ACB056F}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{EAF1312A-B8D9-4021-A2F9-CBB47ACB056F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{EAF1312A-B8D9-4021-A2F9-CBB47ACB056F}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{EAF1312A-B8D9-4021-A2F9-CBB47ACB056F}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{EAF1312A-B8D9-4021-A2F9-CBB47ACB056F}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {78AE15E9-1F4C-4A01-B2C4-ECD52557C553}
24+
EndGlobalSection
25+
EndGlobal

Save In Companion/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
5+
</startup>
6+
</configuration>

Save In Companion/MenuEntry.cs

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Runtime.InteropServices;
6+
7+
8+
namespace Save_In_Companion
9+
{
10+
/// <summary>
11+
/// Class containing methods to retrieve specific file system paths.
12+
/// </summary>
13+
public class MenuEntry
14+
{
15+
public string FolderPath { get; set; }
16+
17+
public string Name { get; set; }
18+
19+
public string Comment { get; set; }
20+
21+
public List<MenuEntry> SubEntries { get; set; }
22+
23+
public int Deepness { get; set; }
24+
25+
public bool IsSeperator { get; set; }
26+
27+
public bool IsCategory { get; set; }
28+
29+
public MenuEntry()
30+
{
31+
SubEntries = new List<MenuEntry>();
32+
}
33+
34+
string GetRootFolder(string path)
35+
{
36+
string rootFolder;
37+
38+
//HACK: I don't know of a good way of handling the root of a linux volume.
39+
if (string.IsNullOrEmpty(path))
40+
{
41+
rootFolder = "SaveInRoot";
42+
}
43+
else
44+
{
45+
rootFolder = path;
46+
47+
while (true)
48+
{
49+
string temp = Path.GetDirectoryName(path);
50+
if (String.IsNullOrEmpty(temp))
51+
break;
52+
path = temp;
53+
}
54+
}
55+
return rootFolder;
56+
}
57+
58+
public void BuildOutput(StringWriter stream, Settings settings)
59+
{
60+
if (IsSeperator)
61+
{
62+
stream.WriteLine("---");
63+
}
64+
else if (IsCategory)
65+
{
66+
if (SubEntries.Count > 0)
67+
{
68+
stream.WriteLine(string.Format(". // (alias:{0})", Name));
69+
SubEntries.ForEach(x => x.BuildOutput(stream, settings));
70+
}
71+
}
72+
else
73+
{
74+
string finalPath;
75+
76+
if (FolderPath.StartsWith(settings.DownloadsFolderPath))
77+
{
78+
if (FolderPath == settings.DownloadsFolderPath)
79+
{
80+
finalPath = string.Format(". //{0} (alias: {1})", Comment, Name);
81+
}
82+
else
83+
{
84+
finalPath = FolderPath.Remove(0, settings.DownloadsFolderPath.Length + 1);
85+
}
86+
}
87+
else
88+
{
89+
// Get the drive prefix.
90+
string drivePrefix = Path.GetPathRoot(FolderPath);
91+
92+
// Get the folder path with the drive prefix removed
93+
string relativePath = FolderPath.Remove(0, drivePrefix.Length);
94+
95+
// Get the safe identifier of the drive
96+
char[] arr = drivePrefix.ToCharArray();
97+
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c)
98+
|| char.IsWhiteSpace(c)
99+
|| c == '-')));
100+
string driveLetter = new string(arr);
101+
102+
// Get the root folder of the relative path.
103+
string rootFolder = GetRootFolder(relativePath);
104+
105+
// create final written path
106+
finalPath = string.Format("{0}{1} //{2} (alias:{3})", new string('>', Deepness),
107+
Path.Combine(settings.SaveInLinksFolderName, driveLetter + relativePath), Comment, Name);
108+
109+
if (!settings.SkipLinkCreation)
110+
{
111+
// Create a link path.
112+
string link = Path.Combine(settings.SaveInLinksFolderPath, driveLetter + rootFolder);
113+
114+
if (!Directory.Exists(link))
115+
{
116+
string realPath;
117+
118+
// Get real path folder
119+
//HACK:
120+
if (rootFolder == "SaveInRoot")
121+
{
122+
realPath = "/";
123+
}
124+
else
125+
{
126+
realPath = Path.Combine(drivePrefix, rootFolder);
127+
128+
}
129+
CreateSymbolicLink(link, realPath);
130+
}
131+
}
132+
}
133+
134+
// Write the final path
135+
stream.WriteLine(finalPath);
136+
137+
// Do all of this for each sub entry and so on.
138+
SubEntries.ForEach(x => x.BuildOutput(stream, settings));
139+
}
140+
}
141+
142+
private void CreateSymbolicLink(string linkPath, string realPath)
143+
{
144+
Process process = new Process();
145+
ProcessStartInfo startInfo = new ProcessStartInfo();
146+
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
147+
148+
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
149+
{
150+
startInfo.FileName = "ln";
151+
152+
startInfo.Arguments = string.Format("-s {0} {1}", realPath, linkPath);
153+
}
154+
else
155+
{
156+
startInfo.FileName = "cmd.exe";
157+
158+
string linktype;
159+
if (IsUserAnAdmin()) linktype = "D";
160+
else linktype = "J";
161+
162+
startInfo.Arguments = string.Format("/C mklink /{0} {1} {2}", linktype, linkPath, realPath);
163+
}
164+
165+
process.StartInfo = startInfo;
166+
167+
process.Start();
168+
169+
// Wait for finish, else this will get called several times in a tight loop
170+
process.WaitForExit();
171+
}
172+
173+
174+
[DllImport("shell32.dll", SetLastError = true)]
175+
[return: MarshalAs(UnmanagedType.Bool)]
176+
static extern bool IsUserAnAdmin();
177+
178+
public void LoadSubdirectories(Settings settings)
179+
{
180+
if (FolderPath == settings.SaveInLinksFolderPath || FolderPath == null || FolderPath == string.Empty)
181+
{
182+
return;
183+
}
184+
185+
try
186+
{
187+
string[] subdirectoryEntries = Directory.GetDirectories(FolderPath);
188+
189+
if (subdirectoryEntries.Length > 0)
190+
{
191+
for (int i = 0; i < subdirectoryEntries.Length; i++)
192+
{
193+
SubEntries.Add(new MenuEntry() { FolderPath = subdirectoryEntries[i], Name = Path.GetFileName(subdirectoryEntries[i]), Deepness = this.Deepness + 1 });
194+
SubEntries[i].LoadSubdirectories(settings);
195+
}
196+
197+
if (!settings.DisableLinkBack)
198+
{
199+
string insertName = settings.BackLinkStartText + this.Name + settings.BackLinkEndText;
200+
201+
202+
if (settings.IncludeNameInBackLink)
203+
insertName = settings.BackLinkStartText + this.Name + settings.BackLinkEndText;
204+
else
205+
insertName = settings.BackLinkStartText + settings.BackLinkEndText;
206+
207+
MenuEntry entry = new MenuEntry() { FolderPath = this.FolderPath, Name = insertName, Deepness = this.Deepness + 1 };
208+
209+
if (settings.LinkBackOnBottom)
210+
SubEntries.Add(entry);
211+
else
212+
SubEntries.Insert(0, entry);
213+
}
214+
}
215+
else if (!settings.DisableLinkBack && settings.ForceLinkBack && Deepness > 0)
216+
{
217+
string insertName = settings.BackLinkStartText + this.Name + settings.BackLinkEndText;
218+
219+
220+
if (settings.IncludeNameInBackLink)
221+
insertName = settings.BackLinkStartText + this.Name + settings.BackLinkEndText;
222+
else
223+
insertName = settings.BackLinkStartText + settings.BackLinkEndText;
224+
225+
MenuEntry entry = new MenuEntry() { FolderPath = this.FolderPath, Name = insertName, Deepness = this.Deepness + 1 };
226+
227+
228+
SubEntries.Add(entry);
229+
}
230+
}
231+
catch (UnauthorizedAccessException)
232+
{
233+
return;
234+
}
235+
catch (DirectoryNotFoundException) // Probably a broken link within the path, in this context..
236+
{
237+
return;
238+
}
239+
//TODO: Should probably give some feedback.
240+
catch (PathTooLongException)
241+
{
242+
return;
243+
}
244+
245+
}
246+
247+
public override string ToString()
248+
{
249+
if (IsSeperator)
250+
{
251+
return "###Seperator###";
252+
}
253+
else if (IsCategory)
254+
{
255+
return string.Format("Category: {0}", Name);
256+
}
257+
else
258+
{
259+
if (Comment != string.Empty && Comment != null)
260+
{
261+
return string.Format("{0} (Name: {1}) (Comment: {2})", FolderPath, Name, Comment);
262+
}
263+
else
264+
{
265+
return string.Format("{0} (Name: {1})", FolderPath, Name);
266+
}
267+
}
268+
}
269+
}
270+
}

Save In Companion/Program.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using System.Windows.Forms;
6+
7+
namespace Save_In_Companion
8+
{
9+
static class Program
10+
{
11+
/// <summary>
12+
/// The main entry point for the application.
13+
/// </summary>
14+
[STAThread]
15+
static void Main()
16+
{
17+
Application.EnableVisualStyles();
18+
Application.SetCompatibleTextRenderingDefault(false);
19+
Application.Run(new SaveInCompanionForm());
20+
}
21+
}
22+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("Save In Companion")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("Save In Companion")]
13+
[assembly: AssemblyCopyright("Copyright © 2019")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("eaf1312a-b8d9-4021-a2f9-cbb47acb056f")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]

0 commit comments

Comments
 (0)