forked from zbrad/EmacsKeys
-
Notifications
You must be signed in to change notification settings - Fork 25
/
EmacsEmulationPackage.cs
107 lines (95 loc) · 4.45 KB
/
EmacsEmulationPackage.cs
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
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using System.IO;
using EnvDTE;
using System.Windows.Forms;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Text.Editor;
using System.Security.Principal;
using System.Reflection;
using System.Threading;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.Editor.EmacsEmulation
{
/// <summary>
/// This is the class that implements the package exposed by this assembly.
///
/// The minimum requirement for a class to be considered a valid package for Visual Studio
/// is to implement the IVsPackage interface and register itself with the shell.
/// This package uses the helper classes defined inside the Managed Package Framework (MPF)
/// to do it: it derives from the Package class that provides the implementation of the
/// IVsPackage interface and uses the registration attributes defined in the framework to
/// register itself and its components with the shell.
/// </summary>
// This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
// a package.
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
// This attribute is used to register the informations needed to show the this package
// in the Help/About dialog of Visual Studio.
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
// This attribute is needed to let the shell know that this package exposes some menus.
//[ProvideMenuResource("Menus.ctmenu", 1)]
[Guid("d88ec9a6-cdda-4b04-8e46-ca81a3997a3a")]
[ProvideAutoLoad(UIContextGuids.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
public sealed class EmacsEmulationPackage : AsyncPackage
{
const string InstallFilename = "EmacsSetup.bat";
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
await base.InitializeAsync(cancellationToken, progress);
var componentModel = await this.GetServiceAsync(typeof(SComponentModel)) as IComponentModel;
var manager = componentModel.GetService<EmacsCommandsManager>();
try
{
// if the emacs keybindings are not installed and the user is not running elevated
// then we need to copy the emacs.vsk for our extension to work
// get an ok from the user first
if (!manager.IsEmacsVskInstalled)
{
string installPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
installPath = Path.Combine(installPath, EmacsCommandsManager.EmacsVskFile);
var dlg = new CopyFileConfirmationDialog();
dlg.StartPosition = FormStartPosition.CenterScreen;
if (IsAdministrator || dlg.ShowDialog() == DialogResult.OK)
{
CopyVskUsingXCopy(installPath, manager);
}
}
}
catch (Exception)
{
}
manager.CheckEmacsVskSelected();
}
private void CopyVskUsingXCopy(string installPath, EmacsCommandsManager manager)
{
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = @"xcopy.exe";
process.StartInfo.Arguments = string.Format(@"""{0}"" ""{1}""", installPath, manager.EmacsInstallationPath);
if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major > 5)
{
process.StartInfo.Verb = "runas";
}
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
}
bool IsAdministrator
{
get
{
WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);
return wp.IsInRole(WindowsBuiltInRole.Administrator);
}
}
}
}