SushiHangover

PowerShell, Learn it or Perish ;-)

master nix
Gitter

Adding nuget packages to your MonoDevelop Addin Templates

I recently created nugets for the PlayScript AOT assemblies as well as a separtate MSBuild target nuget and it ended up working really well in a x-plat way.

But one thing that I could not find quickly was how to tag my templates with the package info so they are automatically installed when the solution/projects are created.

Well the answer was kind-of right under my nose (RTFM):

Conditionally Adding a NuGet Package from a Project Template A NuGet package be conditionally installed based on a boolean parameter defined by the project template wizard.

<Packages>
    <Package id="Xamarin.GooglePlayServices" version="19.0.0.1" if="UseGooglePlayServices" />
</Packages>

The conditions that can be specified do not support the more complicated condition that grouped templates do.

Re: Conditionally Adding a NuGet Package from a Project Template

So in my templates I currently do not have to lock them to a version and want the most recent ones available so I skip the version attribute:

<Packages>
    <Package id="PlayScript.AOT" />
    <package id="PlayScript.MSBuild" />
</Packages>

MSBuild / xbuild - Steps of a build

I’m working on adding MSBuild style building to PlayScript.

The end goal is two fold.

1st) To support the standard MSBuild process in order to allow VS/MD/XS’s IDEs to use this std process via the project file’s target import tag.

2nd) Can I replace the compile portion of the process (with the PlayScript compiler) so I directly create Xamarin.Mac, Xamarin.iOS and Xamarin.Android libraries that are written in PlayScript/ActionScript by using Xamarin’s custom MSBuild process, but via a different compiler that produces the IL code?

A compiled PlayScript library (or exe) is just a standard CIL assembly and can be referenced by C# projects, Xamarin mobile projects or not, but directly referencing Xamarin iOS, Android or Mac libraries will not work as those project types are special (mainly licensing checks and build steps). So the 2nd part of this is really an experient is to see if we are stuck to only linking to PlayScript libraries or can we use PlayScript to directly code against the Xamarin’s mobile libraries and still comply with their licensing/build process.

Building via the psc CLI compiler is almost identical to using csc or mcs. There are a few different options are available in order to support some of the ActionScript 3 compiler options, but I digress…

The normal MSBuild / xbuild steps to compile a CSharp project (.csproj) involved the following high-level Targets:

  • PrepareForBuild:
  • CopyFilesMarkedCopyLocal:
  • GenerateSatelliteAssemblies:
  • CoreCompile:
  • DeployOutputFiles:

Ignoring the multimedia pipeline processing of assets (images, SWFs, vector transformations, 3D models, etc..) the only step that we need to focus on is the CoreCompile:

Import Project=“$(MSBuildBinPath)\Microsoft.CSharp.targets”

~~~
<Target
        Name="CoreCompile"
        Inputs="$(MSBuildAllProjects);@(Compile);@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile);
                $(KeyOriginatorFile);@(ReferencePath);$(Win32Icon);$(Win32Resource)"
        Outputs="@(DocFileItem);@(IntermediateAssembly)"
        DependsOnTargets="$(CoreCompileDependsOn)">
        <Csc
                AdditionalLibPaths="$(AdditionalLibPaths)"
                AddModules="@(AddModules)"
                AllowUnsafeBlocks="$(AllowUnsafeBlocks)"
                BaseAddress="$(BaseAddress)"
~~~
                Win32Icon="$(Win32Icon)"
                Win32Resource="$(Win32Resource)"
                Resources="@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile)"
                ToolExe="$(CscToolExe)"
                ToolPath="$(CscToolPath)" />

</Target>
~~~

Looking at the Csc section, if I can replace ToolExe and CscToolPath properties then I can have this Target use PlayScript (psc) vs. csc or mcs.

So as a quick test, copying Microsoft.CSharp.targets to PlayScript.MSBuild.Targetsand adding thisPropertyGroupsection with hardcoded paths before theCoreCompile` target section:

    <PropertyGroup>
            <PlayScriptBinPath Condition=" '$(PsBuildBinPath)' == '' ">/Users/sushi/Library/Application Support/XamarinStudio-5.0/LocalInstall/Addins/MonoDevelop.PlayScript.5.10.2/MonoDevelop.PlayScript.SupportPackages</PlayScriptBinPath>
            <CscToolExe Condition=" '$(CscToolExe)' == '' ">psc</CscToolExe>
            <CscToolPath Condition=" '$(CscToolPath)' == '' ">$(PsBuildBinPath)</CscToolPath>
    </PropertyGroup>

And replacing:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

with:

<Import Project="packages\PlayScript.MSBuild.5.10.2.2\build\PlayScript.MSBuild.Targets" />

>xbuild nuget-test.psproj

XBuild Engine Version 12.0
Mono, Version 4.2.2.0
Copyright (C) 2005-2013 Various Mono authors

Build started 1/1/2016 11:05:25 AM.
__________________________________________________
Project "/Users/sushi/code/XamTests/nuget-test/nuget-test.psproj" (default target(s)):
    Target PrepareForBuild:
        Configuration: Debug Platform: x86
    Target BeforeResolveReferences:
                         AssemblySearchPaths: {CandidateAssemblyFiles};{HintPathFromItem};{TargetFrameworkDirectory};{PkgConfig};{GAC};{RawFileName};bin/Debug/;/Users/sushi/mono/play32/bin
    Target GenerateSatelliteAssemblies:
    No input files were specified for target GenerateSatelliteAssemblies, skipping.
    Target GenerateTargetFrameworkMonikerAttribute:
    Skipping target "GenerateTargetFrameworkMonikerAttribute" because its outputs are up-to-date.
    Target CoreCompile:
         psc
         /Users/sushi/mono/play32/bin

        Tool /Users/sushi/mono/play32/bin/psc execution started with arguments: /noconfig /debug:full /debug+ /optimize- /out:obj/x86/Debug/nuget-test.exe Main.play /target:exe /define:DEBUG /nostdlib /platform:x86 /reference:/Library/Frameworks/Mono.framework/Versions/4.2.2/lib/mono/4.5/System.dll /reference:packages/PlayScript.AOT.5.10.2.0/lib/net45/PlayScript.Dynamic_aot.dll /reference:packages/PlayScript.AOT.5.10.2.0/lib/net45/pscorlib_aot.dll /reference:/Library/Frameworks/Mono.framework/Versions/4.2.2/lib/mono/4.5/System.Core.dll /reference:/Library/Frameworks/Mono.framework/Versions/4.2.2/lib/mono/4.5/mscorlib.dll /warn:4
    Target DeployOutputFiles:
        Copying file from '/Users/sushi/code/XamTests/nuget-test/obj/x86/Debug/nuget-test.exe.mdb' to '/Users/sushi/code/XamTests/nuget-test/bin/Debug/nuget-test.exe.mdb'
        Copying file from '/Users/sushi/code/XamTests/nuget-test/obj/x86/Debug/nuget-test.exe' to '/Users/sushi/code/XamTests/nuget-test/bin/Debug/nuget-test.exe'
Done building project "/Users/sushi/code/XamTests/nuget-test/nuget-test.psproj".

Build succeeded.
     0 Warning(s)
     0 Error(s)

Time Elapsed 00:00:01.8555370

That works, cool

But that requires mod'ing complete copy of Microsoft.CSharp.targets.

So lets strip out everything but our PlayScript changes and import the std CSharp targets.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

    <PropertyGroup>
        <DefaultLanguageSourceExtension>.cs</DefaultLanguageSourceExtension>
        <Language>PlayScript</Language>
    </PropertyGroup>

<!-- PlayScript -->
    <PropertyGroup>
        <PlayScriptBinPath Condition=" '$(PsBuildBinPath)' == '' ">/Users/sushi/Library/Application Support/XamarinStudio-5.0/LocalInstall/Addins/MonoDevelop.PlayScript.5.10.2/MonoDevelop.PlayScript.SupportPackages</PlayScriptBinPath>
        <CscToolExe Condition=" '$(CscToolExe)' == '' ">psc</CscToolExe>
        <CscToolPath Condition=" '$(CscToolPath)' == '' ">$(PsBuildBinPath)</CscToolPath>
    </PropertyGroup>
<!-- PlayScript -->

<!--
    Note: Microsoft.CSharp.targets already imports Microsoft.Common.targets
          so if we need to override/replacement would need to do it after the 
          Microsoft.CSharp.targets import either in this file or by importing another
          file, i.e. PlayScript.Common.targets
          (this is where we will include our multimedia pipeline tasks)
    <Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
-->

<!-- PlayScript -->
    <Target Name="BeforeResolveReferences">
        <CreateProperty
            Value="$(AssemblySearchPaths);$(PsBuildBinPath)">
            <Output TaskParameter="Value" PropertyName="AssemblySearchPaths" />
        </CreateProperty>
    </Target>
<!-- PlayScript -->

    <Import Project="$(MSBuildThisFileDirectory)\PlayScript.MSBuild.Debug.Targets" />
</Project>

That works…

We still need to look into the custom Xamarin Mobile targets and remove the hardcoded paths from our PlayScript targets, but lets leave that for another post.

C# AppleScript calls with functions, arguments and results

Posted a new C# library to Github to allow the calling of AppleScript by function name, passing in arguments and receiving a return value.

Sushi.AppleScript

https://github.com/sushihangover/Sushi.AppleScript

The C# library allows you to execute AppleScript code that originates from a file or string and:

  • Call function by name (Optional)
  • Pass multiple arguments to a function (Optional)
  • Execution success or failure
  • Return results from the function call

Build:

cd Sushi.AppleScript.Native
xcodebuild
cd -
xbuild Sushi.AppleScript.sln

Test:

Mono’s supplied nunit-console:

MONO_IOMAP=all nunit-console Sushi.AppleScript.Test/SushiAppleScript.Test.csproj

NUnit 3.x console:

mono $(MTOOLS)/nunit3-console.exe Sushi.AppleScript.Test/SushiAppleScript.Test.csproj

Note:

AppleScript.cs(7,7): error CS0246: The type or namespace name `MonoMac' could not be found. Are you missing an assembly reference?

If you do not have a local copy of MonoMac, xbuild will fail. It is available via “Xamarin Studio”:

mdtool build Sushi.AppleScript.sln

Example Usage:

var scptInfo = new FileInfo ("./AppleScripts/FunctionTests.txt");
string funcName = "IsRunning";
List<string> argList = new List<string> () {
    @"Finder",
};
string scriptReturnValue;
var executionSuccess = AppleScript.Run (scptInfo, funcName, argList, out scriptReturnValue);
  • Consult Test.cs for more examples

Supports:

  • MonoMac
  • Xamarin.Mac
  • i386 and x86_64 Mono Support

Runtime/Deployment debugging:

Runtime/Deployment debugging available by setting an environment variable, APPLE_SCRIPT_DEBUG:

export APPLE_SCRIPT_DEBUG=true

The results are logged with the prefix AppleScript:, output is avaiable via Console.app.

Sushi.AppleScript

The C# library that provides the P/Invoke wrapper to execute AppleScript functions

Sushi.AppleScript.Native

An OS-X Universial (i386 & x86_64) Shared Library:

  • libAppleScriptEvent.dylib

Sushi.AppleScript.Test

NUnit tests for Sushi.AppleScript library

Sushi.AppleScript.CLI

TODO: Provides an osascript style CLI utility to execute functions with AppleScript files (osascript does not contain this feature)

License:

  • The MIT License (MIT)

Xamarin Android C# bindings for Java CIFS (jCIFS) Client Library (Samba)

I posted a Samba/JCIFS binding library to my Github account…

Xamarin.Android.jCIFS

This is a C# binding library for the The Java CIFS (jCIFS) Client Library (version 1.3.18).

JCIFS is an Open Source client library that implements the CIFS/SMB networking protocol in 100% Java.

You can read/write, delete, make directories, rename, list contents of a directory, list the workgroups/ntdomains and servers on the network, list the shares of a server, open named pipes, authenticate web clients …etc.

License:

As JCIFS is Licensed Under the LGPL, so is this project’s license.

API Documentation:

Consult the jCIFS site for API documention and usage, this is a C# binding library and does not implement/change anything within the jcifs-1.3.18.jar.

Example:

Usage of Jcifs.Smb.SmbFileInputStream:

// This is NOT best-practice code, just showing a demo Jcifs api call
public async Task getFileContents ()
{
    await Task.Run (() => {
        var smbStream = new SmbFileInputStream ("smb://guest@10.10.10.5/code/test.txt");
        byte[] b = new byte[8192];
        int n;
        while ((n = smbStream.Read (b)) > 0) {
            Console.Write (Encoding.UTF8.GetString (b).ToCharArray (), 0, n);
        }
        Button button = FindViewById<Button> (Resource.Id.myButton);
        RunOnUiThread(() => {
            button.Text = Encoding.UTF8.GetString (b);
        });
    }
    ).ContinueWith ((Task arg) => {
        Console.WriteLine (arg.Status);
        if (arg.Status == TaskStatus.Faulted)
            Console.WriteLine (arg.Exception);
    }
    );
}

Note:

The entire jCIFS library is not bound by this project, consult the “Metadata.xml” file in the binding project for method renames and class exclusions.

Using redirection within xargs

I needed to convert a bunch of AppleScript .scpt files to uncompiled .txt files, so a simple find piped to xargs and I’ll be done… well…

OS-X provides a osadecompile cmd that will read a .scpt file and output the text to stdout (It does not provide a output file option). So a simple redirection and I should be done:

# This will not work, you will end up with a file 
# named {}.txt that includes the test of all the scripts
find *.scpt -print0 | xargs -0 -n 1 -I {} osadecompile '{}' > '{}.txt' 

But that will not work as the redirection applies to the xargs cmd, not the osadecompile cmd that xargs is calling. So a quick fix is to create a subshell and include the redirection in the passed cmd string (via -c)

So this will work:

find *.scpt -print0 | xargs -0 -n 1 -I {} sh -c "osadecompile '{}' > '{}.txt'"

Still simple enough, and since I only have a couple of dozen files in this case the performance impact of creaing subshells is not a problem…

Homework: How would you get around this in using a bash one-liner without a subshell?

Xamarin C# UIPickerView

A real quickie example of a UIPickerView: (iOS SDK)

Add a UIPickerView to your xib or Storyboard called slotMachineView and a label (named selectedLbl) to show the currently selected items.

using System;
using UIKit;

namespace Slots
{
    public partial class ViewController : UIViewController
    {
        public ViewController (IntPtr handle) : base (handle)
        {
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();
                slotMachineView.Model = new StackOverflowModel (selectedLbl);
        }

        public override void DidReceiveMemoryWarning ()
        {
            base.DidReceiveMemoryWarning ();
        }
    }

    public class StackOverflowModel : UIPickerViewModel
    {
        static string[] names = new string [] {
            "pscorlib.dll",
            "pscorlib_aot.dll",
            "Mono.PlayScript.dll",
            "PlayScript.Dynamic.dll",
            "PlayScript.Dynamic_aot.dll",
            "PlayScript.Optimization.dll",
            "playshell.exe",
            "psc.exe"
        };

        UILabel lbl;

        public StackOverflowModel (UILabel lbl)
        {
            this.lbl = lbl;
        }

        public override nint GetComponentCount (UIPickerView v)
        {
            return 3;
        }

        public override nint GetRowsInComponent (UIPickerView pickerView, nint component)
        {
            return names.Length;
        }

        public override string GetTitle (UIPickerView picker, nint row, nint component)
        {
            switch (component) {
            case 0:
                return names [row];
            case 1:
                return row.ToString ();
            case 2:
                return new string ((char)('A' + row), 1);
            default:
                throw new NotImplementedException ();
            }
        }

        public override void Selected (UIPickerView picker, nint row, nint component)
        {
            lbl.Text = String.Format ("{0} : {1} : {2}",
                names [picker.SelectedRowInComponent (0)],
                picker.SelectedRowInComponent (1),
                picker.SelectedRowInComponent (2));
        }

        public override nfloat GetComponentWidth (UIPickerView picker, nint component)
        {
            if (component == 0)
                return 220f;
            else
                return 30f;
        }
    }
}

From my answer on StackOverflow.

Safari - Changing the Quit Shortcut

I tend to hit the Cmd-Q instead of Cmd-W when I am closing a tab and in my older installs on OS-X I had changed the shortcut for Safari Quit and that is one thing (among others) that I did not migrate to my new OS-X 10.11 install.

So, open up System Perferences and go to KeyBoards and then the Shortcuts pane and add an App Shortcuts for Safari only for the menu item called Quit Safari, mine now is Ctrl-CMD-Q:

MonoMac - Demo / Samples updated

A number of the MonoMac demos were broken in various ways so as I was using some of them in my PlayScript / ActionScript work with Stage3d, Away3d and Starling, I update the PlayScriptRedux MonoMac repo with the corrected versions.

./AnimatingViews/bin/Debug/AnimatingViews.app
./attic/Hello/Hello.app
./ButtonMadness/bin/Debug/ButtonMadness.app
./CAQuartzComposition/bin/Debug/CAQuartzComposition.app
./CoreAnimationBook/BackgroundFilteredView/bin/Debug/BackgroundFilteredView.app
./CoreAnimationBook/CustomAnimationTiming/bin/Debug/CustomAnimationTiming.app
./CoreAnimationBook/CustomizeAnimation/bin/Debug/CustomizeAnimation.app
./CoreAnimationBook/CustomizeAnimation2/bin/Debug/CustomizeAnimation.app
./CoreAnimationBook/FilteredView/bin/Debug/FilteredView.app
./CoreAnimationBook/GroupAnimation/bin/Debug/GroupAnimation.app
./CoreAnimationBook/KeyFrameMoveAView/bin/Debug/KeyFrameMoveAView.app
./CoreAnimationBook/LayerBackedControls/bin/Debug/LayerBackedControls.app
./CoreAnimationBook/QCBackground/bin/Debug/QCBackground.app
./CoreAnimationBook/TimedAnimation/bin/Debug/TimedAnimation.app
./CoreTextArcMonoMac/bin/Debug/CoreTextArcMonoMac.app
./CoreWLANWirelessManager/bin/Debug/CoreWLANWirelessManager.app
./DatePicker/bin/Debug/DatePicker.app
./DockAppIcon/bin/Debug/DockAppIcon.app
./DocumentSample/bin/Debug/DocumentSample.app
./DrawerMadness/DrawerMadness/bin/Debug/DrawerMadness.app
./Fire/bin/Debug/Fire.app
./GLFullScreen/bin/Debug/GLFullScreen.app
./GlossyClock/bin/Debug/GlossyClock.app
./GLSLShader/bin/Debug/GLSLShader.app
./ImageKitDemoStep1/bin/Debug/ImageKitDemo.app
./macdoc/bin/Debug/macdoc.app
./MonoMacGameWindow/bin/Debug/MonoMacGameView.app
./NSAlert/bin/Debug/NSAlertSample.app
./NSTableViewBinding/bin/Debug/NSTableViewBinding.app
./OpenGL-NeHe/NeHeLesson1/bin/Debug/NeHeLesson1.app
./OpenGL-NeHe/NeHeLesson13/bin/Debug/NeHeLesson13.app
./OpenGL-NeHe/NeHeLesson17/bin/Debug/NeHeLesson17.app
./OpenGL-NeHe/NeHeLesson2/bin/Debug/NeHeLesson1.app
./OpenGL-NeHe/NeHeLesson3/bin/Debug/NeHeLesson1.app
./OpenGL-NeHe/NeHeLesson4/bin/Debug/NeHeLesson4.app
./OpenGL-NeHe/NeHeLesson5/bin/Debug/NeHeLesson5.app
./OpenGL-NeHe/NeHeLesson6/bin/Debug/NeHeLesson6.app
./OpenGL-NeHe/NeHeLesson7/bin/Debug/NeHeLesson7.app
./OpenGL-NeHe/NeHeLesson8/bin/Debug/NeHeLesson8.app
./OpenGL-NeHe/NeHeLesson9/bin/Debug/NeHeLesson9.app
./OpenGLLayer/bin/Debug/OpenGLLayer.app
./OpenGLViewSample/OpenGLViewSample/bin/Debug/MMOpenTK.app
./PopupBindings/bin/Debug/PopupBindings.app
./PredicateEditorSample/bin/Debug/PredicateEditorSample.app
./QTRecorder/bin/Debug/QTRecorder.app
./RoundedTransparentWindow/bin/Debug/RoundedTransparentWindow.app

MonoMac - Where is the CAEmitterCell Content propery?

I was trying to integrate ActionScript and Away3d with the CAEmitterCell particles using MonoMac for users that do not have access (a license) to Xamarin.Mac, but…

The MonoMac project is missing the maccore CoreAnimation/CAEmitterCell.cs in the Make.shared and thus the MonoMac.dll that is distributed via Xamarin Studio is broken in this regard as it is missing the ability to assign an Image to the emitter.

Example:

            // Create the fire emitter cell
            CAEmitterCell fire = CAEmitterCell.EmitterCell ();
            fire.EmissionLongitude = (float)Math.PI;
            fire.BirthRate = 0;
            fire.Velocity = 80;
            fire.VelocityRange = 30;
            fire.EmissionRange = 1.1f;
            fire.AccelerationY = 200;
            fire.ScaleSpeed = 0.3f;

            RectangleF rect = RectangleF.Empty;
            CGColor color = new CGColor (0.8f,0.4f,0.2f,0.10f);
            fire.Color = color;
            fire.Contents = NSImage.ImageNamed ("fire.png").AsCGImage (ref rect, null, null);

I have updated PlayScript’s MonoMac (forked from Mono/MonoMac) to fix this.

git diff src/Make.shared

diff --git a/src/Make.shared b/src/Make.shared
index 986ff28..a84aeae 100644
--- a/src/Make.shared
+++ b/src/Make.shared
@@ -44,6 +44,7 @@ SHARED_SOURCE = \
        ./CoreAnimation/CALayer.cs                      \
        ./CoreAnimation/CATextLayer.cs                  \
        ./CoreAnimation/CAMediaTimingFunction.cs        \
+       ./CoreAnimation/CAEmitterCell.cs                \
        ./CoreFoundation/CFArray.cs                     \
        ./CoreFoundation/CFBoolean.cs                   \
        ./CoreFoundation/CFDictionary.cs                \

CursesSharp (C# NCurses) Updated

I made some updates to the CursesSharp project, so check out the update README.md for details:

CursesSharp

INTRODUCTION

CursesSharp is a C# wrapper for curses library. The latest version of this ‘fork’‘ can be found at Github. The original version can be found at the SourceForge.net project page.

RainDemo

DOCUMENTATION

CursesSharp consists of a .NET assembly (CursesSharp.dll) and a native wrapper shared library (DLL) which is linked with PDCurses (in Windows) or ncurses (in Unix-like systems). This wrapper library is called CursesWrapper.dll in Windows or libCursesWrapper.so in Unix or libCursesWrapper.dylib in OS-X. CursesSharp provides a bit cleaner API to curses than the original one, although function names remain unchanged for the most part.

CursesSharp namespace contains several important classes:

  • Defs - contains constants from curses: attribute, color and key definitions as well as some macros (COLOR_PAIR, PAIR_NUMBER)
  • Curses - the main interface to curses; contains methods global to the library, a StdScr property that returns the stdscr window, and as a convenience, some window-specific functions that operate on stdscr
  • Window - represents a curses window that can be written to, or read from; contains wrappers for most of curses functions with names starting with w or mvw
  • CursesException - an exception class, thrown when a curses function reports an error

Documentation is (always) under construction. Help would be much appreciated.

Installing CursesSharp on OS-X

These are the instructions for building CursesSharp on OS-X.

The build process has been tested on:

  • OS-X 10.10.5
  • Apple LLVM version 7.0.0 (clang-700.1.76)
  • Mono JIT compiler version 4.2.1 64-bit build.

0. Prerequisites

The native library is now built as a ‘fat’ library so either a Mono 32-bit or 64-bit build can be used.

$> file libCursesWrapper.so

libCursesWrapper.so: Mach-O universal binary with 2 architectures
libCursesWrapper.so (for architecture i386):    Mach-O dynamically linked shared library i386
libCursesWrapper.so (for architecture x86_64):  Mach-O 64-bit dynamically linked shared library x86_64

1. Getting CursesSharp

You can clone it from the following repository:

https://github.com/sushihangover/CursesSharp.git

2. Make the Native Library

mdtool build CursesSharp.Native.sln --target:Build --configuration:Release
mdtool build CursesSharp.Native.sln --target:Build --configuration:Debug

3. Make the C# Libraries and Demos

xbuild CursesSharp.sln /target:Clean
xbuild CursesSharp.sln /target:Build

Note: To run the demos from the CLI, make sure that set the DYLD_FALLBACK_LIBRARY_PATH. While still in the repo’s root directory:

export DYLD_FALLBACK_LIBRARY_PATH=$(PWD)/CursesSharp.Native/bin/Debug:/usr/lib:$DYLD_FALLBACK_LIBRARY_PATH

There is also a CI script that can be called via source to setup DYLD_FALLBACK_LIBRARY_PATH and LD_LIBRARY_PATH

source CI/libpath-source-me.sh

To learn more about dyld check out the man page:

man dyld

Demos:

There are various demos available to review:

  • Demo.CursesSharp.Firework
  • Demo.CursesSharp.Gui.HelloWorld
  • Demo.CursesSharp.HelloWorld
  • Demo.CursesSharp.Rain
  • Demo.CursesSharp.Unicode
  • Demo.Gui.MessageBox
  • Demo.Gui.MidnightCommander
  • Demo.Gui.Timeout
  • Demo.Native.ResizeTerm

Rain Demo:

pushd CursesSharp.Demo/Demo.CursesSharp.Rain/bin/x64/Debug/
mono RainDemo.exe
popd

RainDemo

FireWorks Demo:

pushd CursesSharp.Demo/Demo.CursesSharp.Rain/bin/x64/Debug/
mono FireworkDemo.exe
popd

MidnightCommander Demo:

pushd CursesSharp.Demo/Demo.Gui.MidnightCommander/bin/x64/Debug/
mono Demo.Gui.MidnightCommander.exe
popd

Installing CursesSharp on Linux

0. Prerequisites

Note: It is assumed you are running 64-bit Linux (ARCH x86_64)

Install some dependencies:

sudo apt-get install lib32ncursesw5-dev
sudo apt-get install lib32ncurses5-dev
sudo apt-get install ncurses-doc

1. Getting CursesSharp

You will have to obtain CursesSharp sources. You clone it from the following repository:

https://github.com/sushihangover/CursesSharp.git

2. Make the Native Library

mdtool build CursesSharp.Native.Linux.sln --target:Build --configuration:Release
mdtool build CursesSharp.Native.Linux.sln --target:Build --configuration:Debug

3. Make the C# Libraries and Demos

xbuild CursesSharp.sln /target:Clean /property:configuration=Debug
xbuild CursesSharp.sln /target:Build /property:configuration=Debug

Demos:

Note: To run the demos from the CLI, make sure that set the LD_LIBRARY_PATH. While still in the repo’s root directory:

export LD_LIBRARY_PATH=$(PWD)/CursesSharp.Native/bin/Debug:/usr/lib:$LD_LIBRARY_PATH

There is also a CI script that can be called via source to setup DYLD_FALLBACK_LIBRARY_PATH and LD_LIBRARY_PATH

source CI/libpath-source-me.sh

To learn more about ld check out the man page:

man ld

MessageBox Demo:

cd CursesSharp.Demo/Demo.Gui.MidnightCommander/bin/x64/Debug/
mono Demo.Gui.Messagebox.exe
cd -
(Ubuntu / Konsole)

MidnightCommander Demo:

cd CursesSharp.Demo/Demo.Gui.MidnightCommander/bin/x64/Debug/
mono Demo.Gui.MidnightCommander.exe
cd -

(Ubuntu / Konsole)

Installing CursesSharp on Windows

Refer the original Windows project, source code and instructions are here

CI

OS-X:

source CI/libpath-source-me.sh
CI/build.osx.sh

Linux:

{TODO}

TODO & Contributors:

  • Nuget support
  • MS Window support (via PDCurses)
  • Documentation
  • Bug reporting/fixes

Looking for contributors in these areas and/or any other areas that you would help out on.

Fork and Contribute ;-)