VS2022 set working folder
Tags: dotnet, csharp
Published: 2023-01-02 23:33:03

Many applications use their executable folder for creating and accessing various forms of files while an alternative is to use a folder devoid of the folder where the executable resides or any sub folder, this project show how to create a working folder using MS-Build task.

- First decide on the folder to perform work e.g. read/write to files or open a database
- Next create a variable in a `PropertyGroup` as shown below `WorkingFolder` as we need it in to places
- Create a `Target` for creating the folder indicated above before the build process takes place which uses [MakeDir](https://learn.microsoft.com/en-us/visualstudio/msbuild/makedir-task?view=vs-2022) task to create the folder
- Create a `PropertyGroup` to set the working forlder using [RunWorkingDirectory](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#runworkingdirectory). The RunWorkingDirectory property defines the working directory for the application process to be started in. It can be an absolute path or a path that's relative to the project directory. If you don't specify a directory, `OutDir` is used as the working directory.

Example First decide on the folder to perform work e.g. read/write to files or open a database
- Next create a variable in a `PropertyGroup` as shown below `WorkingFolder` as we need it in to places
- Create a `Target` for creating the folder indicated above before the build process takes place which uses [MakeDir](https://learn.microsoft.com/en-us/visualstudio/msbuild/makedir-task?view=vs-2022) task to create the folder
- Create a `PropertyGroup` to set the working forlder using [RunWorkingDirectory](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#runworkingdirectory). The RunWorkingDirectory property defines the working directory for the application process to be started in. It can be an absolute path or a path that's relative to the project directory. If you don't specify a directory, OutDir is used as the working directory.

## Example for file operations 

Set the working folder to `C:\Work`. Open the project file by clicking on the project name in Solution Explorer. Add the following.

```xml
<PropertyGroup>
	<WorkFolder>C:\Work</WorkFolder>
</PropertyGroup>

<Target Name="MakeWorkFolder" BeforeTargets="Build">
	<MakeDir Directories="$(WorkFolder)" />
</Target>

<PropertyGroup>
	<RunWorkingDirectory>$(WorkFolder)</RunWorkingDirectory>
</PropertyGroup>
```

Now use the following to create a new text file

```csharp
File.WriteAllText("test.txt", "hello");
```

Without added the task to the project file the code above would write to the application folder but with the MS-Build Task the file is created under C:\Work.

## Example working with EF Core SqlLite

The following defines the DbContext which normally creates `file.db` in the application folder but since we set the working folder to C:\Work this is where the database is created.

```csharp
public class Context : DbContext
{
    public DbSet<FileContainer> FileContainers { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder.UseSqlite("Data Source=files.db");
}
```
On a similar note, suppose there are unit test that send messages to a specific folder? When working by yourself simply create the folder under the application folder e.g. call it MailDrop. But when working with a team of developers they must manually create the needed folder. A better idea is to use a MS-Build task.

```xml
<Target Name="MakeMailDir" AfterTargets="Build">
	<MakeDir Directories="$(OutDir)MailDrop" />
</Target>
```
## Source code

See the following [GitHub repository](https://github.com/karenpayneoregon/ms-build-examples), project [MsBuildWorkingDirApp](https://github.com/karenpayneoregon/ms-build-examples/tree/master/MsBuildWorkingDirApp)

## Requires

Microsoft [Visual Studio 2022](https://visualstudio.microsoft.com/)