C# Mode

This action type for work with C# compiler - feel free with all events & actions.

Available control of caching bytecode and full access to ICommand & ISolutionEvent (see /Events)

Default Entry point

using ICommand = net.r_eg.vsSBE.Actions.ICommand;
using ISolutionEvent = net.r_eg.vsSBE.Events.ISolutionEvent;

namespace vsSolutionBuildEvent
{
    public class CSharpMode
    {
        public static int Init(ICommand cmd, ISolutionEvent evt)
        {
            return 0;
        }
    }
}

Compiler settings

References

Additional assembly names that are referenced by the source to compile. You can use any formats below, for example:

EnvDTE.dll
C:\WINDOWS\assembly\GAC\EnvDTE\<ver>\EnvDTE.dll
EnvDTE
EnvDTE, Version=8.0.0.0, PublicKeyToken=b03f5f7f11d50a3a
$(vsSBE_LibPath)EnvDTE.dll

FilesMode flag

As variant, you can also use FilesMode flag in Compiler settings for work with external source codes.

Then you should use list of files instead of code, for example:

hooks\*.cs
scripts\vssbe\main.cs
scripts\vssbe\ftp.cs
D:\app\scripts\*.*

So you can also add this in your solution for more productive work, for example:

Build Scripts for C# Mode

Note: In most cases the Build Action should be as None

ICommand & ISolutionEvent objects

The default entry point provides accessing to next objects:

As you can see, you may work with most operations of vsSolutionBuildEvent core, for example:

Work with MSBuild & SBE-Scripts engine

Define UserVariable with value from C# code

You have a few variants for work with UserVariables:

  • Parse data via engines:
    • SBE-Scripts: cmd.SBEScript.parse(...); (see also ISBEScript)
    • MSBuild: cmd.MSBuild.parse(...); (see also IMSBuild)
  • Direct access to IUserVariable object with used Bootloader (see also IBootloader):
    • cmd.SBEScript.Bootloader.UVariable

SBE-Scripts engine. For example:

Stack<string> mv = new Stack<string>();
mv.Push("One");
mv.Push("Two");
mv.Push("Three");

string data = String.Format("#[var mvMap = {0}]", String.Join(";", mv.ToArray()));
cmd.SBEScript.parse(data);

As result you can get this value from other actions with standard operations, for example:

  • $(mvMap) and #[var mvMap] - should return value: 'Three;Two;One'

Please note:

For work with msbuild properties in C# code if used the MSBuild support, for example:

using(StreamReader reader = new StreamReader(@"$(SolutionPath)", Encoding.Default)) {
    cmd.MSBuild.parse(String.Format("$(mvMap = '{0}')", steps.Peek()));
}

Do not forget escape an sequences to avoid evaluation: $(SolutionPath) -> $$(SolutionPath) [?]

For SBE-Scripts: all elements inside quotes ("...", '...') will be automatically protected from evaluation. [?]

Examples

The optional ICommand & ISolutionEvent objects contains most useful points for work with our core. For example:

  • Access to IEnvironment for getting current build action type:
if(cmd.Env.BuildType != BuildType.Clean) {
    String.Format("Current type: {0}", cmd.Env.BuildType); // Current type: Rebuild
    ...
}
  • Or direct access to User-variables (IUserVariable) for get/set/or evaluation new variables…
IUserVariable uvar = cmd.SBEScript.Bootloader.UVariable;
if(!uvar.isExist("name1", "projectA")) {
    uvar.set("ret", null, "raw");
    ...
}

etc.

Path to solution directory

The most easy way provide data via MSBuild Property $(SolutionDir). Enable MSBuild Support and use like this:

System.Diagnostics.Process.Start(@"$(SolutionDir)submodules.bat").WaitForExit();
string path1 = "$(SolutionDir.Replace('\', '\\'))";
string path2 = "$(SolutionDir.Replace('\', '/'))";
...

Visual Studio OutputWindow pane through vsSBE

OutputWindow

For example below we'll use IOW, but you can also prepare it manually via DTE2 etc.

  • Activate C# Mode
  • Add 'EnvDTE' reference in Compiler - References
    • Use SmartReferences option for automatically finding, including used domain. Or use any available syntax for assemblies.
  • Customize cache and check other available flags of optimization. (optional)
  • Use the following code, for example:
using net.r_eg.vsSBE;
using ICommand = net.r_eg.vsSBE.Actions.ICommand;
using ISolutionEvent = net.r_eg.vsSBE.Events.ISolutionEvent;

namespace vsSolutionBuildEvent
{
    public class CSharpMode
    {
        public static int Init(ICommand cmd, ISolutionEvent evt)
        {
            IOW pane = cmd.Env.OutputWindowPane;
            pane.getByName("Custom Name", true).OutputString(" Hello World! ");
            
            return 0;
        }
    }
}
  • Activate Event and click Apply.

Using directly SBE-Scripts engine

Parsing data via SBE-Scripts engine from C# Mode, yes it's possible. So you can simply:

cmd.SBEScript.parse("#[OWP item(\"My Log\").writeLine(true): Hi :) ]");

As you can see you have a few variants for any cases. However, the Script Mode is more right choice if you want simple access to VS Output window.

FTP. Upload Artefacts and similar

v0.12.6+ is already contains features for work with remote servers. Use FileComponent

  • Activate C# Mode
  • Add 'System.dll' reference in Compiler - References
  • Customize cache and check other available flags of optimization. (optional)
  • Use next code, for example:
using System;
using System.Net;
using ICommand = net.r_eg.vsSBE.Actions.ICommand;
using ISolutionEvent = net.r_eg.vsSBE.Events.ISolutionEvent;

namespace vsSolutionBuildEvent
{
    public class CSharpMode
    {
        public static int Init(ICommand cmd, ISolutionEvent evt)
        {
            _Ftp ftp = new _Ftp("192.168.17.04:2021");
            try {
                ftp.upload("Hello World!", "result.log");
                //ftp.upload(System.IO.File.ReadAllBytes("bin/rel/artefact.data"), "01.data");
            }
            catch {
                return 202;
            }
            return 0;
        }
        
        private class _Ftp
        {
            protected WebClient client;
            protected string server;
    
            public void upload(string data, string to)
            {
                client.UploadString(server + to, data);
            }
    
            public void upload(byte[] data, string to)
            {
                client.UploadData(server + to, data);
            }
    
            public _Ftp(string server, string user = "anonymous", string pass = "")
            {
                client = new WebClient() {
                    Credentials = new NetworkCredential(user, pass)
                };
                this.server = String.Format("ftp://{0}/", server);
            }
        }
    }
}

References