AppDomain.CurrentDomain.BaseDirectory changes to wrong directory - c#

I have a created a dll with a Cmdlet command (see Get_DemoNames.cs). From this cmdlet I call a method UpdateXml(), so far everything is working. But UpdateXml() also creates files if they don't exist. When I call UpdateXml() in a class file like this:
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:
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. At
line:1 char: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. At line:1
char: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();
}
}
}
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)?

Okay, so you're trying to access a project, loaded within Visual Studio, from within the Package Manager Console.
Know that the executable is Visual Studio, and so AppDomain.CurrentDomain.BaseDirectory is going to be the Visual Studio install directory. 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. Typically that's done by writing an extension or via the Visual Studio core automation, AKA the 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. 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.
Those are the pieces and parts you need. As for calling the cmdlet from your code, that's another question.

FIX
I managed to get it working with the following code
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.
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);
}

Related

Cannot get SyntaxTree from Compilation object

I'm a beginner of roslyn, so I tried to start learning it by making a very simple console application, which is introduced in the famous tutorial site. (https://riptutorial.com/roslyn/example/16545/introspective-analysis-of-an-analyzer-in-csharp), and it didn't work well.
The Cosole Application I made is of .NET Framework (target Framework version is 4.7.2), and not of .NET Core nor .NET standard.
I added the NuGet package Microsoft.CodeAnalysis, and Microsoft.CodeAnalysis.Workspaces.MSBuild, then wrote a simple code as I show below.
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using System;
using System.Linq;
namespace SimpleRoslynConsole
{
class Program
{
static void Main(string[] args)
{
// Declaring a variable with the current project file path.
// *** You have to change this path to fit your development environment.
const string projectPath =
#"C:\Users\[MyName]\Source\Repos\RoslynTrialConsole01\RoslynTrialConsole01.csproj";
var workspace = MSBuildWorkspace.Create();
var project = workspace.OpenProjectAsync(projectPath).Result;
// [**1]Getting the compilation.
var compilation = project.GetCompilationAsync().Result;
// [**2]As this is a simple single file program, the first syntax tree will be the current file.
var syntaxTree = compilation.SyntaxTrees.FirstOrDefault();
if (syntaxTree != null)
{
var rootSyntaxNode = syntaxTree.GetRootAsync().Result;
var firstLocalVariablesDeclaration = rootSyntaxNode.DescendantNodesAndSelf()
.OfType<LocalDeclarationStatementSyntax>().First();
var firstVariable = firstLocalVariablesDeclaration.Declaration.Variables.First();
var variableInitializer = firstVariable.Initializer.Value.GetFirstToken().ValueText;
Console.WriteLine(variableInitializer);
}
else
{
Console.WriteLine("Could not get SyntaxTrees from this projects.");
}
Console.WriteLine("Hit any key.");
Console.ReadKey();
}
}
}
My problem is that, SyntaxTrees property of Compilation object returns null in [**2]mark. Naturally, following FirstOrDefault method returns null.
I've tried several other code. I found I could get SyntaxTree from CSharp code text, by using CSharpSyntaxTree.ParseText method. But I couldn't get any from source code, by the sequence of
var workspace = MSBuildWorkspace.Create();
var project = workspace.OpenProjectAsync(projectPath).Result;
var compilation = project.GetCompilationAsync().Result;
What I'd like to know is if I miss something to get Syntax information from source code by using above process.
I'll appreciate someone give me a good advice.
I think the issue is that .net framework projects have their source files paths within their .csproj. And opening project works right away.
For .net core project you have no such information and, maybe, this is why Workspace instance doesn't know what to load and so loads nothing.
At least specifying .cs files as added documents does the trick. Try to apply this:
static class ProjectExtensions
{
public static Project AddDocuments(this Project project, IEnumerable<string> files)
{
foreach (string file in files)
{
project = project.AddDocument(file, File.ReadAllText(file)).Project;
}
return project;
}
private static IEnumerable<string> GetAllSourceFiles(string directoryPath)
{
var res = Directory.GetFiles(directoryPath, "*.cs", SearchOption.AllDirectories);
return res;
}
public static Project WithAllSourceFiles(this Project project)
{
string projectDirectory = Directory.GetParent(project.FilePath).FullName;
var files = GetAllSourceFiles(projectDirectory);
var newProject = project.AddDocuments(files);
return newProject;
}
}
Method WithAllsourceFiles will return you the project, compilation of which will in its turn have all syntax trees you would expect of it, as you would have in Visual Studio
MsBuildWorkspace won't work correctly unless you have all the same redirects in your app's app.config file that msbuild.exe.config has in it. Without the redirects, it's probably failing to load the msbuild libraries. You need to find the msbuild.exe.config file that is on your system and copy the <assemblyBinding> elements related to Microsoft.Build assemblies into your app.config. Make sure you place them under the correct elements configuration/runtime.
I searched various sample programs on the net and found the most reliable and safest method. The solution is to create a static method which returns SyntaxTrees in designated File as follow.
private static Compilation CreateTestCompilation()
{
var found = false;
var di = new DirectoryInfo(Environment.CurrentDirectory);
var fi = di.GetFiles().Where((crt) => { return crt.Name.Equals("program.cs", StringComparison.CurrentCultureIgnoreCase); }).FirstOrDefault();
while ((fi == null) || (di.Parent == null))
{
di = new DirectoryInfo(di.Parent.FullName);
fi = di.GetFiles().Where((crt) => { return crt.Name.Equals("program.cs", StringComparison.CurrentCultureIgnoreCase); }).FirstOrDefault();
if (fi != null)
{
found = true;
break;
}
}
if (!found)
{
return null;
}
var targetPath = di.FullName + #"\Program.cs";
var targetText = File.ReadAllText(targetPath);
var targetTree =
CSharpSyntaxTree.ParseText(targetText)
.WithFilePath(targetPath);
var target2Path = di.FullName + #"\TypeInferenceRewriter.cs";
var target2Text = File.ReadAllText(target2Path);
var target2Tree =
CSharpSyntaxTree.ParseText(target2Text)
.WithFilePath(target2Path);
SyntaxTree[] sourceTrees = { programTree, target2Tree };
MetadataReference mscorlib =
MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
MetadataReference codeAnalysis =
MetadataReference.CreateFromFile(typeof(SyntaxTree).Assembly.Location);
MetadataReference csharpCodeAnalysis =
MetadataReference.CreateFromFile(typeof(CSharpSyntaxTree).Assembly.Location);
MetadataReference[] references = { mscorlib, codeAnalysis, csharpCodeAnalysis };
return CSharpCompilation.Create("TransformationCS",
sourceTrees,
references,
new CSharpCompilationOptions(
OutputKind.ConsoleApplication));
}
And the caller program will be like this.
static void Main(string[] args)
{
var test = CreateTestCompilation();
if (test == null)
{
return;
}
foreach (SyntaxTree sourceTree in test.SyntaxTrees)
{
Console.WriteLine(souceTree.ToFullString());
}
}
Of course, many improvements are needed to put it to practical use.

How to use the gRPC tools to generate code

I've read the tutorial and I'm able to generate the .cs file but it doesn't include any of my service or rpc definitions.
I've added protoc to my PATH and from inside the project directory.
protoc project1.proto --csharp_out="C:\output" --plugin=protoc-gen-grpc="c:\Users\me\.nuget\packages\grpc.tools\1.8.0\tools\windows_x64\grpc_csharp_plugin.exe"
No errors output in console
You need to add the --grpc_out command line option, e.g. add
--grpc_out="C:\output\"
Note that it won't write any files if you don't have any services.
Here's a complete example. From a root directory, create:
An empty output directory
A tools directory with protoc.exe and grpc_csharp_plugin.exe
A protos directory with test.proto as shown below:
test.proto:
syntax = "proto3";
service StackOverflowService {
rpc GetAnswer(Question) returns (Answer);
}
message Question {
string text = 1;
string user = 2;
repeated string tags = 3;
}
message Answer {
string text = 1;
string user = 2;
}
Then run (all on one line; I've broken it just for readability here):
tools\protoc.exe -I protos protos\test.proto --csharp_out=output
--grpc_out=output --plugin=protoc-gen-grpc=tools\grpc_csharp_plugin.exe
In the output directory, you'll find Test.cs and TestGrpc.cs
Just an idle comment here for other that find this, the documentation about this is terribly out of date and just flat out wrong.
Installing Grpc.Tools does not install anything in a packages folder; that is legacy behaviour which is no longer true even on windows.
When you install Grpc.Tools it will be hidden away in your local package cache, which you can see by calling:
$ dotnet nuget locals all --list
info : http-cache: /Users/doug/.local/share/NuGet/v3-cache
info : global-packages: /Users/doug/.nuget/packages/
info : temp: /var/folders/xx/s2hnzbrj3yn4hp1bg8q9gb_m0000gn/T/NuGetScratch
The binaries you want will be in one of these folders.
The easiest way to do this is to download the Grpc.Tools package directly from nuget, and install it locally.
I've hacked up this little helper script to do that, which works on windows/mac/linux, which may ease the difficulty of getting starting with this for others:
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Mono.Unix;
namespace BuildProtocol
{
public class Program
{
private const string ToolsUrl = "https://www.nuget.org/api/v2/package/Grpc.Tools/";
private const string Service = "Greeter";
private static string ProtocolPath = Path.Combine("..", "protos");
private static string Protocol = Path.Combine(ProtocolPath, "helloworld.proto");
private static string Output = Path.Combine("..", "Greeter");
public static void Main(string[] args)
{
RequireTools().Wait();
var protoc = ProtocPath();
var plugin = ProtocPluginPath();
Console.WriteLine($"Using: {protoc}");
Console.WriteLine($"Using: {plugin}");
var command = new string[]
{
$"-I{ProtocolPath}",
$"--csharp_out={Output}",
$"--grpc_out={Output}",
$"--plugin=protoc-gen-grpc=\"{plugin}\"",
Protocol,
};
Console.WriteLine($"Exec: {protoc} {string.Join(' ', command)}");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
FileName = protoc,
Arguments = string.Join(' ', command)
}
};
process.Start();
process.WaitForExit();
Console.WriteLine($"Completed status: {process.ExitCode}");
}
public static async Task RequireTools()
{
if (!Directory.Exists("Tools"))
{
Console.WriteLine("No local tools found, downloading binaries from nuget...");
Directory.CreateDirectory("Tools");
await DownloadTools();
ExtractTools();
}
}
private static void ExtractTools()
{
ZipFile.ExtractToDirectory(Path.Combine("Tools", "tools.zip"), Path.Combine("Tools", "bin"));
}
private static async Task DownloadTools()
{
using (var client = new HttpClient())
{
Console.WriteLine($"Fetching: {ToolsUrl}");
using (var result = await client.GetAsync(ToolsUrl))
{
if (!result.IsSuccessStatusCode) throw new Exception($"Unable to download tools ({result.StatusCode}), check URL");
var localArchive = Path.Combine("Tools", "tools.zip");
Console.WriteLine($"Saving to: {localArchive}");
File.WriteAllBytes(localArchive, await result.Content.ReadAsByteArrayAsync());
}
}
}
private static string ProtocPath()
{
var path = Path.Combine("Tools", "bin", "tools", DetermineArch(), "protoc");
RequireExecutablePermission(path);
return WithExeExtensionIfRequired(path);
}
private static string ProtocPluginPath()
{
var path = Path.Combine("Tools", "bin", "tools", DetermineArch(), "grpc_csharp_plugin");
RequireExecutablePermission(path);
return WithExeExtensionIfRequired(path);
}
private static void RequireExecutablePermission(string path)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
Console.WriteLine($"Ensuring +x on {path}");
var unixFileInfo = new UnixFileInfo(path);
unixFileInfo.FileAccessPermissions = FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite | FileAccessPermissions.UserExecute;
}
private static string WithExeExtensionIfRequired(string path)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
path += ".exe";
}
return path;
}
private static string DetermineArch()
{
var arch = RuntimeInformation.OSArchitecture;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return WithArch("windows_", arch);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return WithArch("macosx_", arch);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return WithArch("linux_", arch);
}
throw new Exception("Unable to determine runtime");
}
private static string WithArch(string platform, Architecture arch)
{
switch (arch)
{
case Architecture.X64:
return $"{platform}x86";
case Architecture.X86:
return $"{platform}x64";
default:
throw new ArgumentOutOfRangeException(nameof(arch), arch, null);
}
}
}
}
the following approach helped me :
Create a gRPC client and server in ASP.NET Core
in project, where .proto file located, edit the .csproj file
<ItemGroup>
....
<Protobuf Include="Shipping.proto" GrpcServices="Server" />
</ItemGroup>
rebuild the project, the all necessary .cs files will be added automaticaly
\obj\Debug\[TARGET_FRAMEWORK]\Shipping.cs
\obj\Debug\[TARGET_FRAMEWORK]\ShippingGrpc.cs

Creating folder in VSO via VSO API

I have been trying to figure out how is possible to create a query folder via VSO api, but I always the "Method not allowed" message.
I'm using Microsoft.TeamFoundationServer.Client package to connect VSO. This page says that this library is needed for me. I can query data, but it seems something is missing to create data. This library is fit for me because I have a WebApi whihch manages the communication to VSO API.
Here is my code:
public QueryHierarchyItem CreateFolderAsync(string folderName)
{
QueryHierarchyItem newFolder = new QueryHierarchyItem()
{
Name = folderName,
IsFolder = true,
//Path = "Queries/Shared Queries/" + folderName,
IsPublic = true
};
QueryHierarchyItem item = witClient.CreateQueryAsync(newFolder, _projectName, null).Result;
return item;
}
I have tried to play with the Path property but it did not help.
I have checked the user rights. My user is member of "Project Administrators", and
rights are also set up to manage query folders (Click the chevron next to the "Shared Queries" folder -> select "Security") as group and as single user. It did not help.
I use a free account. The strange is that I have logged in with the same user from Visual Studio and I can manage the folders. Is this functionality available for free accounts?
You can refer to this blog from MSDN for details: http://blogs.msdn.com/b/team_foundation/archive/2010/06/16/work-item-tracking-queries-object-model-in-2010.aspx
Quote the code here:
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace QueryAPI
{
class Program
{
private static Project myproject = null;
public static QueryFolder GetMyQueriesFolder()
{
foreach (QueryFolder folder in myproject.QueryHierarchy)
{
if (folder.IsPersonal == true)
return folder;
}
throw new Exception("Cannot find the My Queries folder");
}
public static QueryFolder AddNewFolder(string folderName)
{
QueryFolder folder = new QueryFolder(folderName, GetMyQueriesFolder());
myproject.QueryHierarchy.Save();
return folder;
}
static void Main(string[] args)
{
TfsTeamProjectCollection coll = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("Your TFS Server URI"));
WorkItemStore store = new WorkItemStore(coll);
myproject = store.Projects["Your project name"];
QueryFolder myNewfolder = AddNewFolder("Your folder name");
}
}
}

How can I set sort of "Start in"-path for a Windows Service

I have following class, which is used by a Windows Installer project, to install a service:
[RunInstaller(true)]
public sealed class Installer : System.Configuration.Install.Installer
{
private readonly string _installDir;
public Installer()
{
var locatedAssembly = this.GetType().Assembly.Location;
this._installDir = Path.GetDirectoryName(locatedAssembly);
var serviceProcessInstaller = new ServiceProcessInstaller
{
Account = ServiceAccount.LocalSystem
};
var serviceInstaller = new ServiceInstaller
{
ServiceName = Settings.Service.Name,
StartType = ServiceStartMode.Automatic
};
this.Installers.Add(serviceProcessInstaller);
this.Installers.Add(serviceInstaller);
this.Context = new InstallContext(this._installDir + #"\install.log", new[]
{
string.Format("/assemlypath={0}", locatedAssembly)
});
}
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
var serviceController = new ServiceController(Settings.Service.Name);
serviceController.Start();
serviceController.WaitForStatus(ServiceControllerStatus.Running);
}
}
If we call the following code inside a console application, the directory of the assembly will be taken:
using (var stream = File.Open("foo.store", FileMode.OpenOrCreate))
If I run the line from my Windows Service, C:\Windows\System32\ will be taken instead.
How can I change this behaviour?
For clarification: I do not want to utilize any assembly-spying (get the path of the assembly from this.GetType()...) or anything in the appsettings. I want it to work straight without any magic on the caller side :)
Don't trust the current directory. If the file is located besides the service use:
string sdir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
to recover the path in which the executable is, and use it as a base path to look for the file.
You will need to read the folder location from a configuration file, or the registry. There's no analogue of starting directory.

After updating EnvironmentVariable - PATH - I still get a FileNotFoundException on Windows 2003 Server

I'm just starting with a new product and I guess I don't understand the PATH variable. My documentation says to update the PATH like this which I do successfully in a little console application:
using HP.HPTRIM.SDK;
namespace TestSDKforTRIM71
{
class Program
{
static void Main(string[] args)
{
string trimInstallDir = #"C:\Program Files\Hewlett-Packard\HP TRIM";
string temp = Environment.GetEnvironmentVariable("PATH") + ";" + trimInstallDir;
Environment.SetEnvironmentVariable("PATH", temp);
DoTrimStuff();
}
public static void DoTrimStuff()
{
using (Database db = new Database())
{
db.Connect();
Console.WriteLine(db.Id);
}
Console.ReadKey();
}
}
}
In the above project, I have a reference to HP.HPTRIM.SDK which exists at:
C:\Program Files\Hewlett-Packard\HP TRIM\HP.HPTRIM.SDK.dll
After the above ran successfully, I tried to permanently change the PATH by using Control Panel:System:Advanced:Environment Variables. I verified the above PATH by examining the registry at HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. I see the following as the last entry in the PATH value:
;C:\Program Files\Hewlett-Packard\HP TRIM\
I thought this would permanently SET this at the end of the PATH but when I run the above console program with a few lines commented out I get the FileNotFoundException (see below). I am confused about how to get this in the PATH and not have to worry about it anymore.
using HP.HPTRIM.SDK;
namespace TestSDKforTRIM71
{
class Program
{
static void Main(string[] args)
{
//string trimInstallDir = #"C:\Program Files\Hewlett-Packard\HP TRIM";
//string temp = Environment.GetEnvironmentVariable("PATH") + ";" + trimInstallDir;
//Environment.SetEnvironmentVariable("PATH", temp);
DoTrimStuff(); // without setting the PATH this fails despite being in REGISTRY...
}
public static void DoTrimStuff()
{
using (Database db = new Database())
{
db.Connect();
Console.WriteLine(db.Id);
}
Console.ReadKey();
}
}
}
Only newly started processes that don't inherit their environment from their parent will have the updated PATH. You'll have to at least restart the Visual Studio hosting process, close and re-open your solution. To cover all possible corners, log out and log back in so that Windows Explorer (and thus Visual Studio) also start using the updated environment.

Categories

Resources