How get the current running Visual Studio installation path from VSPackage

1.5k views Asked by At

I've created a VSPackage which should copy some XML schema files to Visual Studio's installation path: %VS install path% \Xml\Schemas.

I have multiple Visual Studios installed on my machine:

  • Visual Studio 2013 Professional.
  • Visual Studio 2015 Community Edition.
  • Visual Studio Express Editions.

I need to detect the path to the Visual Studio from which my VSPackage is executing its command.

How can I get the current running Visual Studio's installation path in the package?

3

There are 3 answers

2
Matze On BEST ANSWER

First, I agree with Carlos in that particular point that an extension should never require elevated priviledges. But that does not mean, your problem cannot be solved; I would just suggest to do it in another way...

I had a similiar issue with one of my extensions; and I was looking for a solution which would not require a Windows installer setup, but work for pure VSIX packages. I solved it by creating a small console application, which I referenced by my package assembly. I added an application manifest to the console application, allowing me to request the required execution level; for instance:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

The console application looks like...

public class HelperExe
{
    public static int Main(params string[] args)
    {
        // TODO: 
    }
}

The console application will do the work that requires elevated priviledges. The package creates a new process using the Process class; the image´s file path can be obtained from the defining assembly (because this might be a random path, if the package is installed from VSIX).

var consoleAssemblyLocation = new Uri(typeof(HelperExe).Assembly.CodeBase);
var file = new FileInfo(consoleAssemblyLocation.LocalPath);
if (file.Exists)
{
    var consoleProcess = new Process 
    {
        StartInfo = new ProcessStartInfo(file.FullName)
        {
            CreateNoWindow = true
        }
    };

    consoleProcess.Start();
    var timeout = (int)TimeSpan.FromMinutes(5).TotalMilliseconds;
    consoleProces.WaitForExit(timeout);
}

Since the manifest will involve the UAC to elevate the process... this has also the nice side-effect, that the user can cancel that operation. Make sure that your extension can handle that...

Visual Studio´s installation folder can be read from the registry; you can pass the obtained path to the console application via a commandline argument. I did it like this...

static string GetVisualStudioInstallationFolder(string visualStudioVersion)
{
    string subKeyName = string.Format(
        CultureInfo.InvariantCulture, 
        @"Software\Microsoft\VisualStudio\{0}_Config", 
        visualStudioVersion);

    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyName))
    {
        if (key != null)
        {
            return (string)key.GetValue("ShellFolder");
        }
    }

    return null;
}

The visualStudioVersion parameter can be obtained from the DTE.Version property...

0
Carlos Quintero On

Your package will not be able to copy files to the VS installation path because admin rights are required for that and VS doesn't run elevated (with admin rights) by default, and a package should not force VS to run elevated. The setup of your package could do that, but not your package.

That said, see:

HOWTO: Get information about the Visual Studio IDE from a Visual Studio package.

0
A-Sharabiani On

Finally managed to find the installation path with the following code:

   var test = ((EnvDTE.DTE)ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE).GUID)).FullName;
   VISUAL_STUDIO_INSTALLATION_PATH = Path.GetFullPath(Path.Combine(test, @"..\..\..\"));

Also for getting the Version of the running Visual Studio:

 EnvDTE.DTE dte = (EnvDTE.DTE)Package.GetGlobalService(typeof(EnvDTE.DTE));
 VISUAL_STUDIO_VERSION = dte.Version;