How get the current running Visual Studio installation path from VSPackage

前端 未结 3 1460
梦毁少年i
梦毁少年i 2021-01-13 20:47

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

相关标签:
3条回答
  • 2021-01-13 21:24

    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 讨论(0)
  • 2021-01-13 21:28

    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 讨论(0)
  • 2021-01-13 21:32

    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;
    
    0 讨论(0)
提交回复
热议问题