-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
159 lines (128 loc) · 4.95 KB
/
Program.cs
File metadata and controls
159 lines (128 loc) · 4.95 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
using System;
using CLAP;
using System.Text.RegularExpressions;
using System.Diagnostics;
using Microsoft.Win32;
namespace ProtocolHandler
{
class Program
{
static void Main(string[] args)
{
try
{
Parser.Run<App>(args);
}
catch(Exception e)
{
#if DEBUG
throw e;
#else
Console.WriteLine(e.Message);
#endif
}
#if DEBUG
Console.ReadLine();
#endif
}
}
class App
{
/// <summary>
/// Open the provided file via the appropriate url-handler. Will be written to the registry as a command
/// </summary>
/// <param name="path">URL/scheme to open</param>
[Verb(IsDefault = true)]
public static void Open(string path)
{
//paths will be url encoded
path = path.UrlDecode();
Console.WriteLine($"trying to resolve {path}");
ProtocolResult proto = ResolveProtocol(path);
if(proto == null)
{
throw new Exception("the protocol could not be resolved");
}
Console.WriteLine($"path resolved to protocol {proto.Protocol} and file {proto.Path}");
Config config = Config.LoadFromRegistry(proto.Protocol);
if(config == null)
{
throw new Exception($"no config found for protocol {proto.Protocol}");
}
Console.WriteLine($"config loaded for protocol {proto.Protocol}");
Console.WriteLine($"opening file {proto.Path} with handler {config.HandlerPath}");
//open file
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = config.HandlerPath;
startInfo.Arguments = $"\"{proto.Path}\" {config.AdditionalArguments}";
Process exeProcess = Process.Start(startInfo);
}
[Verb]
public static void InstallUrlSchemes(string[] schemes, bool forMachine = false)
{
Config.HIVE_KEYS key = Config.HIVE_KEYS.HKCU;
if (Config.IsAdministrator() && forMachine)
{
key = Config.HIVE_KEYS.HKLM;
Console.WriteLine("installing schemes for local machine");
}
else
{
Console.WriteLine("installing schemes for current user");
}
string launchPath = "\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\" Open -path=\"%1\"";
foreach (string scheme in schemes)
{
Console.WriteLine($"installing scheme {scheme}");
string _base = @"Software\Classes\" + scheme;
Config.SetRegistryValue(key, _base, "URL protocol", "", RegistryValueKind.String);
Config.SetRegistryValue(key, _base, "UseOriginalUrlEncoding", 1, RegistryValueKind.DWord);
Config.SetRegistryValue(key, _base + @"\shell\open\command", "", launchPath, RegistryValueKind.String);
}
}
[Verb]
public static void RegisterScheme(string protocol, string handlerPath, string arguments = "", bool forMachine = false, bool install = true)
{
Config.HIVE_KEYS key = Config.HIVE_KEYS.HKCU;
if (Config.IsAdministrator() && forMachine)
{
key = Config.HIVE_KEYS.HKLM;
Console.WriteLine($"registering scheme {protocol} for local machine");
}
else
{
Console.WriteLine($"registering scheme {protocol} for current user");
}
Config.SetRegistryValue(key, Config.REG_BASE + @"\" + protocol, "HandlerPath", handlerPath, RegistryValueKind.String);
if(arguments != "" && arguments != null)
Config.SetRegistryValue(key, Config.REG_BASE + @"\" + protocol, "AdditionalArguments", arguments, RegistryValueKind.String);
if(install)
{
InstallUrlSchemes(new string[] { protocol }, forMachine);
}
}
private static ProtocolResult ResolveProtocol(string path)
{
string[] patterns = new string[]
{
@"(ms-excel):ofe\|u\|(https?:\/\/.*\.xlsx?)",
@"(ms-word):ofe\|u\|(https?:\/\/.*\.docx?)",
@"(ms-powerpoint):ofe\|u\|(https?:\/\/.*\.pptx?)",
@"(mecmrc):\/\/(.*)"
};
ProtocolResult result = null;
foreach(string pattern in patterns)
{
Match match = Regex.Match(path, pattern);
if(match.Success)
{
result = new ProtocolResult(match.Groups[1].Value, match.Groups[2].Value);
break;
}
}
return result;
}
}
}