簡體   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