[英]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.