[英]AppDomain.CurrentDomain.BaseDirectory changes according to the app's target platform
[英]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.