简体   繁体   English

AppDomain.CurrentDomain.BaseDirectory 更改为错误的目录

[英]AppDomain.CurrentDomain.BaseDirectory changes to wrong directory

I have a created a dll with a Cmdlet command (see Get_DemoNames.cs).我使用Cmdlet命令创建了一个dll (请参阅 Get_DemoNames.cs)。 From this cmdlet I call a method UpdateXml() , so far everything is working.我从这个cmdlet调用了一个方法UpdateXml() ,到目前为止一切正常。 But UpdateXml() also creates files if they don't exist.但如果文件不存在, UpdateXml()也会创建文件。 When I call UpdateXml() in a class file like this:当我在这样的类文件中调用UpdateXml()时:

var parser = new Parser();
parser.UpdateXml();

And I run the project it goes to the correct directories.我运行项目,它转到正确的目录。

But if I load the import the dll and run the command DemoNames in a seperate test project like this:但是,如果我加载导入的 dll 并在单独的测试项目中运行命令DemoNames ,如下所示:

PM> Import-Module C:\projects\EF.XML\EF.XML.dll
PM> DemoNames

The program goes to a wrong directory resulting in the following error:程序进入错误目录导致以下错误:

Get-DemoNames : Access to the path 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\beheer_extern\\config' is denied. Get-DemoNames :拒绝访问路径“C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\beheer_extern\\config”。 At line:1 char:10 + DemoNames <<<< + CategoryInfo : NotSpecified: (:) [Get-DemoNames], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,EF.XML.Get_DemoNames在第 1 行字符:10 + DemoNames <<<< + CategoryInfo : NotSpecified: (:) [Get-DemoNames], UnauthorizedAccessException +fullyQualifiedErrorId : System.UnauthorizedAccessException,EF.XML.Get_DemoNames

I searched on the net for this error and found out that some other people were able to solve it by adding this line to the constructor:我在网上搜索了这个错误,发现其他人可以通过将这一行添加到构造函数来解决它:

public Parser()
{
    AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory);
}

This gives me another wrong path:这给了我另一个错误的路径:

Get-DemoNames : Access to the path 'C:\\Windows\\system32\\beheer_extern\\config' is denied. Get-DemoNames :拒绝访问路径“C:\\Windows\\system32\\beheer_extern\\config”。 At line:1 char:10 + DemoNames <<<< + CategoryInfo : NotSpecified: (:) [Get-DemoNames], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,EF.XML.Get_DemoNames在第 1 行字符:10 + DemoNames <<<< + CategoryInfo : NotSpecified: (:) [Get-DemoNames], UnauthorizedAccessException +fullyQualifiedErrorId : System.UnauthorizedAccessException,EF.XML.Get_DemoNames

Get_DemoNames.cs Get_DemoNames.cs

namespace EF.XML
{
using System;
using System.Linq;
using System.Management.Automation;

[Cmdlet(VerbsCommon.Get, "DemoNames")]
public class Get_DemoNames : PSCmdlet
{

    [Parameter(Position = 0, Mandatory = false)]
    public string prefix;

    protected override void ProcessRecord()
    {

        var names = new[] { "Chris", "Charlie", "Isaac", "Simon" };

        if (string.IsNullOrEmpty(prefix))
        {
            WriteObject(names, true);
        }
        else
        {
            var prefixed_names = names.Select(n => prefix + n);

            WriteObject(prefixed_names, true);
        }

        System.Diagnostics.Debug.Write("hello");

        var parser = new Parser();
        parser.UpdateXml();

    }

  }
}

Parser.cs解析器

 public class Parser
{
    public void UpdateXml()
    {
                var directoryInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory); // www directory

                var path = Path.Combine(directoryInfo.FullName, @"beheer_extern\config");

                //Creates the beheer_extern\config directory if it doesn't exist, otherwise nothing happens.
                Directory.CreateDirectory(path);

                var instellingenFile = Path.Combine(path, "instellingen.xml");
                var instellingenFileDb = Path.Combine(path, "instellingenDb.xml");

                //Create instellingen.xml if not already existing
                if (!File.Exists(instellingenFile))
                {
                    using (var writer = XmlWriter.Create(instellingenFile, _writerSettings))
                    {
                        var xDoc = new XDocument(
                            new XElement("database", string.Empty, new XAttribute("version", 4)));
                        xDoc.WriteTo(writer);
                    }
                }
      }
}

How can I get the right directory of the project (www directory)?如何获取项目的正确目录(www 目录)?

Okay, so you're trying to access a project, loaded within Visual Studio, from within the Package Manager Console.好的,所以您正在尝试从包管理器控制台访问一个加载到 Visual Studio 中的项目。

Know that the executable is Visual Studio , and so AppDomain.CurrentDomain.BaseDirectory is going to be the Visual Studio install directory.知道可执行文件是Visual Studio ,因此AppDomain.CurrentDomain.BaseDirectory将成为 Visual Studio 安装目录。 It absolutely will not be the directory of the current project.绝对不会是当前项目的目录。

In order to get the project directory for the currently loaded solution, you need to interact with the running instance of Visual Studio via automation.为了获取当前加载的解决方案的项目目录,您需要通过自动化与正在运行的 Visual Studio 实例进行交互。 Typically that's done by writing an extension or via the Visual Studio core automation, AKA the EnvDTE com object .通常,这是通过编写扩展或通过 Visual Studio 核心自动化(也称为EnvDTE com object)来完成的 This is complex .这很复杂 Want to do this?想要这样做吗? You'll probably have to grab a book on the subject and read.你可能不得不拿起一本关于这个主题的书来阅读。

Luckily, the PMC does provide a cmdlet that will simplify this greatly for you-- get-project .幸运的是,PMC 确实提供了一个 cmdlet,可以为您大大简化此操作—— get-project It returns the DTE representation of the project , which you can then use this to get the project file's full filename , from which you can get the directory name.它返回项目DTE 表示,然后您可以使用它来获取项目文件的完整文件名,您可以从中获取目录名称。

Those are the pieces and parts you need.这些是您需要的零件。 As for calling the cmdlet from your code, that's another question.至于从您的代码调用 cmdlet,那是另一个问题。

FIX使固定

I managed to get it working with the following code我设法使用以下代码使其工作

Get_DemoNames.cs Get_DemoNames.cs

namespace EF.XML
{
using System;
using System.Linq;
using System.Management.Automation;

[Cmdlet(VerbsCommon.Get, "DemoNames")]
public class Get_DemoNames : PSCmdlet
{

[Parameter(Position = 0, Mandatory = false)]
public string prefix;

protected override void ProcessRecord()
{

    var names = new[] { "Chris", "Charlie", "Isaac", "Simon" };

    if (string.IsNullOrEmpty(prefix))
    {
        WriteObject(names, true);
    }
    else
    {
        var prefixed_names = names.Select(n => prefix + n);

        WriteObject(prefixed_names, true);
    }

    //added
    const string networkPath = "Microsoft.PowerShell.Core\\FileSystem::";
    var currentPath = SessionState.Path.CurrentFileSystemLocation.Path;

    var curProjectDir = currentPath.Substring(networkPath.Length); 

    WriteObject(curProjectDir);

    System.Diagnostics.Debug.Write("hello");

    var parser = new Parser {CurrentProjectDirectory = curProjectDir };
    parser.UpdateXml();

    }

  }
}

Parser.cs解析器

public class Parser
{    



public string CurrentProjectDirectory{ get; set; }

public void UpdateXml()
{

    var wwwDirectory = Path.Combine(CurrentProjectDirectory, @"www"); // www directory

    var path = Path.Combine(wwwDirectory, @"beheer_extern\config");

    //Creates the beheer_extern\config directory if it doesn't exist, otherwise nothing happens.
    Directory.CreateDirectory(path);

    var instellingenFile = Path.Combine(path, "instellingen.xml");
    var instellingenFileDb = Path.Combine(path, "instellingenDb.xml");

    //Create instellingen.xml if not already existing
    if (!File.Exists(instellingenFile))
    {
        using (var writer = XmlWriter.Create(instellingenFile, _writerSettings))
        {
            var xDoc = new XDocument(
                new XElement("database", string.Empty, new XAttribute("version", 4)));
            xDoc.WriteTo(writer);
        }
    }
  }
}

I also tried EnvDTE which also works.我也试过EnvDTE ,它也有效。

Required imports:所需的进口:

using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.Shell;

Code to get the current solution (path):获取当前解决方案(路径)的代码:

 DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2;

        if (dte2 != null)
        {
            WriteObject(dte2.Solution.FullName);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AppDomain.CurrentDomain.BaseDirectory会根据应用程序的目标平台进行更改 - AppDomain.CurrentDomain.BaseDirectory changes according to the app's target platform AppDomain.CurrentDomain.BaseDirectory运行测试后会发生变化吗? - AppDomain.CurrentDomain.BaseDirectory changes after running test? 如何模拟AppDomain.CurrentDomain.BaseDirectory - How to mock AppDomain.CurrentDomain.BaseDirectory C#Uri AppDomain.CurrentDomain.BaseDirectory相对路径 - C# Uri AppDomain.CurrentDomain.BaseDirectory relative path 为什么 AppDomain.CurrentDomain.BaseDirectory 在控制台应用程序中定位 bin catelog? - Why is AppDomain.CurrentDomain.BaseDirectory targeting bin catelog in console application? 运行MVC项目时AppDomain.CurrentDomain.BaseDirectory路径问题 - AppDomain.CurrentDomain.BaseDirectory path issue when running MVC project 我应该使用 AppDomain.CurrentDomain.BaseDirectory 还是 System.Environment.CurrentDirectory? - Should I use AppDomain.CurrentDomain.BaseDirectory or System.Environment.CurrentDirectory? 如何通过在 c# 中使用 AppDomain.CurrentDomain.BaseDirectory 在文件夹路径中上一步 - How to go one step above in a folder path by using AppDomain.CurrentDomain.BaseDirectory in c# 为什么 AppDomain.CurrentDomain.BaseDirectory 在 asp.net 应用程序中不包含“bin”? - Why AppDomain.CurrentDomain.BaseDirectory not contains "bin" in asp.net app? AppDomain.CurrentDomain.BaseDirectory和Application.ExecutablePath在实践中有什么区别? - What's the difference between AppDomain.CurrentDomain.BaseDirectory and Application.ExecutablePath in practice?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM