C# AppDomain.CurrentDomain.BaseDirectory更改为错误目录
我使用C# AppDomain.CurrentDomain.BaseDirectory更改为错误目录,c#,pscmdlet,C#,Pscmdlet,我使用Cmdlet命令创建了dll(请参阅Get\u DemoNames.cs)。通过这个cmdlet我调用了一个方法UpdateXml(),到目前为止一切都正常。但是UpdateXml()也会创建不存在的文件。在类文件中调用UpdateXml()时,如下所示: var parser = new Parser(); parser.UpdateXml(); PM> Import-Module C:\projects\EF.XML\EF.XML.dll PM> DemoNames 我
Cmdlet
命令创建了dll
(请参阅Get\u DemoNames.cs)。通过这个cmdlet
我调用了一个方法UpdateXml()
,到目前为止一切都正常。但是UpdateXml()
也会创建不存在的文件。在类文件中调用UpdateXml()
时,如下所示:
var parser = new Parser();
parser.UpdateXml();
PM> Import-Module C:\projects\EF.XML\EF.XML.dll
PM> DemoNames
我运行这个项目,它会进入正确的目录
但是如果我加载导入dll并在单独的测试项目中运行命令DemoNames
,如下所示:
var parser = new Parser();
parser.UpdateXml();
PM> Import-Module C:\projects\EF.XML\EF.XML.dll
PM> DemoNames
程序转到错误目录,导致以下错误:
获取DemoNames:访问路径“C:\Program Files(x86)\Microsoft”
Visual Studio 14.0\Common7\IDE\beheer\u extern\config'被拒绝。在
行:1字符:10
+DemoNames好的,那么您正试图从PackageManager控制台中访问一个在VisualStudio中加载的项目 知道可执行文件是Visual Studio,因此
AppDomain.CurrentDomain.BaseDirectory
将成为Visual Studio安装目录。它绝对不会是当前项目的目录
为了获取当前加载的解决方案的项目目录,您需要通过自动化与正在运行的VisualStudio实例进行交互。通常,可以通过编写扩展或通过VisualStudio核心自动化,即。这很复杂。想这样做吗?你可能得抓起一本关于这个主题的书来读
幸运的是,PMC确实提供了一个cmdlet,它将大大简化这一过程--。它返回,然后您可以使用它获取项目文件的,您可以从中获取目录名
这些是你需要的零件。至于从代码中调用cmdlet,那是另一个问题。FIX
我设法让它与以下代码一起工作
获取_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();
}
}
}
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 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);
}
}
}
}
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;
获取当前解决方案(路径)的代码:
不要将内容保存在可执行文件的子目录下。您应该在AppData下保存数据。@此解决方案是否应该更新需要在
//www/beheer\u extern/config
中包含xml文件的现有项目。我同意在AppData中保存是更好的做法,但我想要的是可能的吗?您是否在visual studio中的powershell中运行此操作?@我是否会在VS包管理器控制台中使用Cmdlet
类和解析器类加载dll
我自己找到了一个修复方法,如果需要,您可以查看我编辑的问题。@Sybren odd,但对你有好处。你不应该在你的问题上加上你的答案。把它作为答案加在这里。等待期结束后,您可以将其选择为正确并结束您的问题。这里就是这样的。另外,如果你能添加更多关于你做了什么以及如何工作的细节,那就太好了。我不明白你的修复程序是如何工作的,我想知道。谢谢。我添加了代码作为答案,我还深入到EnvDTE并将我的“EnvDTE”解决方案添加到了答案中。从我的Cmdlet
dll中,我可以使用您在我的答案中看到的代码获取当前解决方案,我还可以从当前解决方案中获取Parser.cs
类(作为ProjectItem
),方法是:var p=dte2.solution.FindProjectItem(“Parser.cs”)
但是你知道我如何制作解析器实例p
并调用它的方法(UpdateXml
)?@Sybren nope。可能是个新问题,如果你不能解决它。好的,没问题,如果我不能找到如何解决它,我会提出一个新问题。