繁体   English   中英

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

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

我使用Cmdlet命令创建了一个dll (请参阅 Get_DemoNames.cs)。 我从这个cmdlet调用了一个方法UpdateXml() ,到目前为止一切正常。 但如果文件不存在, UpdateXml()也会创建文件。 当我在这样的类文件中调用UpdateXml()时:

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

我运行项目,它转到正确的目录。

但是,如果我加载导入的 dll 并在单独的测试项目中运行命令DemoNames ,如下所示:

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

程序进入错误目录导致以下错误:

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

我在网上搜索了这个错误,发现其他人可以通过将这一行添加到构造函数来解决它:

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

这给了我另一个错误的路径:

Get-DemoNames :拒绝访问路径“C:\\Windows\\system32\\beheer_extern\\config”。 在第 1 行字符:10 + DemoNames <<<< + CategoryInfo : NotSpecified: (:) [Get-DemoNames], UnauthorizedAccessException +fullyQualifiedErrorId : System.UnauthorizedAccessException,EF.XML.Get_DemoNames

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();

    }

  }
}

解析器

 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);
                    }
                }
      }
}

如何获取项目的正确目录(www 目录)?

好的,所以您正在尝试从包管理器控制台访问一个加载到 Visual Studio 中的项目。

知道可执行文件是Visual Studio ,因此AppDomain.CurrentDomain.BaseDirectory将成为 Visual Studio 安装目录。 绝对不会是当前项目的目录。

为了获取当前加载的解决方案的项目目录,您需要通过自动化与正在运行的 Visual Studio 实例进行交互。 通常,这是通过编写扩展或通过 Visual Studio 核心自动化(也称为EnvDTE com object)来完成的 这很复杂 想要这样做吗? 你可能不得不拿起一本关于这个主题的书来阅读。

幸运的是,PMC 确实提供了一个 cmdlet,可以为您大大简化此操作—— get-project 它返回项目DTE 表示,然后您可以使用它来获取项目文件的完整文件名,您可以从中获取目录名称。

这些是您需要的零件。 至于从您的代码调用 cmdlet,那是另一个问题。

使固定

我设法使用以下代码使其工作

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();

    }

  }
}

解析器

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);
        }
    }
  }
}

我也试过EnvDTE ,它也有效。

所需的进口:

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

获取当前解决方案(路径)的代码:

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

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM