Skip to content

Commit e685dfa

Browse files
committed
new: Support Async Package for VS2015 lator #7
1 parent 5965004 commit e685dfa

File tree

7 files changed

+479
-15
lines changed

7 files changed

+479
-15
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
//------------------------------------------------------------------------------
2+
// <copyright file="PackageRegistrationAttribute.cs" company="Microsoft">
3+
// Copyright (c) Microsoft Corporation. All rights reserved.
4+
// </copyright>
5+
//------------------------------------------------------------------------------
6+
// This File came from github.com/Microsoft/VSSDK-Extensibility-Samples
7+
/*
8+
* The MIT License (MIT)
9+
*
10+
* Copyright (c) 2015 Microsoft
11+
*
12+
* Permission is hereby granted, free of charge, to any person obtaining a copy
13+
* of this software and associated documentation files (the "Software"), to deal
14+
* in the Software without restriction, including without limitation the rights
15+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+
* copies of the Software, and to permit persons to whom the Software is
17+
* furnished to do so, subject to the following conditions:
18+
*
19+
* The above copyright notice and this permission notice shall be included in all
20+
* copies or substantial portions of the Software.
21+
*
22+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28+
* SOFTWARE.
29+
*/
30+
namespace Microsoft.VisualStudio.AsyncPackageHelpers {
31+
32+
using System;
33+
using System.Globalization;
34+
using System.IO;
35+
using System.ComponentModel;
36+
using Microsoft.VisualStudio.Shell;
37+
using Microsoft.VisualStudio.Shell.Interop;
38+
39+
/// <devdoc>
40+
/// This attribute is defined on a package to get it to be registered. It
41+
/// is internal because packages are meant to be registered, so it is
42+
/// implicit just by having a package in the assembly.
43+
/// </devdoc>
44+
[AttributeUsage(AttributeTargets.Class, Inherited=true, AllowMultiple=false)]
45+
public sealed class AsyncPackageRegistrationAttribute : RegistrationAttribute
46+
{
47+
private RegistrationMethod registrationMethod = RegistrationMethod.Default;
48+
private bool useManagedResources = false;
49+
private bool allowsBackgroundLoad = false;
50+
private string satellitePath = null;
51+
52+
/// <devdoc>
53+
/// Select between specifying the Codebase entry or the Assembly entry in the registry.
54+
/// This can be overriden during registration
55+
/// </devdoc>
56+
public RegistrationMethod RegisterUsing
57+
{
58+
get
59+
{
60+
return registrationMethod;
61+
}
62+
set
63+
{
64+
registrationMethod = value;
65+
}
66+
}
67+
68+
/// <summary>
69+
/// For managed resources, there should not be a native ui dll registered.
70+
/// </summary>
71+
public bool UseManagedResourcesOnly
72+
{
73+
get { return useManagedResources; }
74+
set { useManagedResources = value; }
75+
}
76+
77+
/// <summary>
78+
/// Package is safe to load on a background thread.
79+
/// </summary>
80+
public bool AllowsBackgroundLoading
81+
{
82+
get { return allowsBackgroundLoad; }
83+
set { allowsBackgroundLoad = value; }
84+
}
85+
86+
/// <summary>
87+
/// To specify a resource dll located in a different location then the default,
88+
/// set this property. This can be useful if your package is installed in the GAC.
89+
/// If this is not set, the directory where the package is located will be use.
90+
///
91+
/// Note that the dll should be located at the following path:
92+
/// SatellitePath\lcid\PackageDllNameUI.dll
93+
/// </summary>
94+
public string SatellitePath
95+
{
96+
get { return satellitePath; }
97+
set { satellitePath = value; }
98+
}
99+
100+
private string RegKeyName(RegistrationContext context)
101+
{
102+
return String.Format(CultureInfo.InvariantCulture, "Packages\\{0}", context.ComponentType.GUID.ToString("B"));
103+
}
104+
105+
/// <devdoc>
106+
/// Called to register this attribute with the given context. The context
107+
/// contains the location where the registration information should be placed.
108+
/// it also contains such as the type being registered, and path information.
109+
///
110+
/// This method is called both for registration and unregistration. The difference is
111+
/// that unregistering just uses a hive that reverses the changes applied to it.
112+
/// </devdoc>
113+
/// <param name="context">
114+
/// Contains the location where the registration information should be placed.
115+
/// It also contains other information such as the type being registered
116+
/// and path of the assembly.
117+
/// </param>
118+
public override void Register(RegistrationContext context) {
119+
Type t = context.ComponentType;
120+
121+
Key packageKey = null;
122+
try
123+
{
124+
packageKey = context.CreateKey(RegKeyName(context));
125+
126+
//use a friendly description if it exists.
127+
DescriptionAttribute attr = TypeDescriptor.GetAttributes(t)[typeof(DescriptionAttribute)] as DescriptionAttribute;
128+
if (attr != null && !String.IsNullOrEmpty(attr.Description)) {
129+
packageKey.SetValue(string.Empty, attr.Description);
130+
}
131+
else {
132+
packageKey.SetValue(string.Empty, t.Name);
133+
}
134+
135+
packageKey.SetValue("InprocServer32", context.InprocServerPath);
136+
packageKey.SetValue("Class", t.FullName);
137+
138+
// If specified on the command line, let the command line option override
139+
if (context.RegistrationMethod != RegistrationMethod.Default)
140+
{
141+
registrationMethod = context.RegistrationMethod;
142+
}
143+
144+
// Select registration method
145+
switch (registrationMethod)
146+
{
147+
case RegistrationMethod.Assembly:
148+
case RegistrationMethod.Default:
149+
packageKey.SetValue("Assembly", t.Assembly.FullName);
150+
break;
151+
152+
case RegistrationMethod.CodeBase:
153+
packageKey.SetValue("CodeBase", context.CodeBase);
154+
break;
155+
}
156+
157+
Key childKey = null;
158+
if (!useManagedResources)
159+
{
160+
try
161+
{
162+
childKey = packageKey.CreateSubkey("SatelliteDll");
163+
164+
// Register the satellite dll
165+
string satelliteDllPath;
166+
if (SatellitePath != null)
167+
{
168+
// Use provided path
169+
satelliteDllPath = context.EscapePath(SatellitePath);
170+
}
171+
else
172+
{
173+
// Default to package path
174+
satelliteDllPath = context.ComponentPath;
175+
}
176+
childKey.SetValue("Path", satelliteDllPath);
177+
childKey.SetValue("DllName", String.Format(CultureInfo.InvariantCulture, "{0}UI.dll", Path.GetFileNameWithoutExtension(t.Assembly.ManifestModule.Name)));
178+
}
179+
finally
180+
{
181+
if (childKey != null)
182+
childKey.Close();
183+
}
184+
}
185+
186+
if (allowsBackgroundLoad)
187+
{
188+
packageKey.SetValue("AllowsBackgroundLoad", true);
189+
}
190+
191+
if (typeof(IVsPackageDynamicToolOwner).IsAssignableFrom(context.ComponentType) ||
192+
typeof(IVsPackageDynamicToolOwnerEx).IsAssignableFrom(context.ComponentType))
193+
{
194+
packageKey.SetValue("SupportsDynamicToolOwner", Microsoft.VisualStudio.PlatformUI.Boxes.BooleanTrue);
195+
}
196+
}
197+
finally
198+
{
199+
if (packageKey != null)
200+
packageKey.Close();
201+
}
202+
}
203+
204+
/// <devdoc>
205+
/// Unregister this package.
206+
/// </devdoc>
207+
/// <param name="context"></param>
208+
public override void Unregister(RegistrationContext context)
209+
{
210+
context.RemoveKey(RegKeyName(context));
211+
}
212+
213+
}
214+
}
215+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// This File came from github.com/Microsoft/VSSDK-Extensibility-Samples
2+
/*
3+
* The MIT License (MIT)
4+
*
5+
* Copyright (c) 2015 Microsoft
6+
* Copyright (c) 2019 Yutaka TSUMORI
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all
16+
* copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
using System;
28+
using Microsoft.VisualStudio.Shell.Interop;
29+
using System.Threading.Tasks;
30+
using Microsoft.VisualStudio.Shell;
31+
32+
namespace Microsoft.VisualStudio.AsyncPackageHelpers
33+
{
34+
public static class ExtensionMethods
35+
{
36+
/// <summary>
37+
/// Helper method to use async/await with IAsyncServiceProvider implementation
38+
/// </summary>
39+
/// <param name="asyncServiceProvider">IAsyncServciceProvider instance</param>
40+
/// <param name="serviceType">Type of the Visual Studio service requested</param>
41+
/// <returns>Service object as type of T</returns>
42+
public static async Task<T> GetServiceAsync<T>(this IAsyncServiceProvider asyncServiceProvider, Type serviceType) where T : class
43+
{
44+
// We have to make sure we are on main UI thread before trying to cast as underlying implementation
45+
// can be an STA COM object and doing a cast would require calling QueryInterface/AddRef marshaling
46+
// to main thread via COM.
47+
return await System.Threading.Tasks.Task.Run(async () =>
48+
{
49+
Guid serviceTypeGuid = serviceType.GUID;
50+
return await asyncServiceProvider.QueryServiceAsync(ref serviceTypeGuid);
51+
}).ConfigureAwait(true) as T;
52+
}
53+
54+
/// <summary>
55+
/// Gets if async package is supported in the current instance of Visual Studio
56+
/// </summary>
57+
/// <param name="serviceProvider">an IServiceProvider instance, usually a Package instance</param>
58+
/// <returns>true if async packages are supported</returns>
59+
public static bool IsAsyncPackageSupported(this IServiceProvider serviceProvider)
60+
{
61+
IAsyncServiceProvider asyncServiceProvider = serviceProvider.GetService(typeof(SAsyncServiceProvider)) as IAsyncServiceProvider;
62+
return asyncServiceProvider != null;
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)