Get current filename of .cs

634 views
Skip to first unread message

Tarmo Pikaro

unread,
Nov 22, 2012, 4:34:18 PM11/22/12
to cs-s...@googlegroups.com
Hi !

I was looking for analogue of __FILE__ in C++, and found that for C# it's 
            string fileName=new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName();

But c# scripter returns null for fileName.
Is there any other way for C# scripter ?

My target is to get self modifying code I guess...  :-)

Oleg Shilo

unread,
Nov 22, 2012, 4:45:47 PM11/22/12
to cs-s...@googlegroups.com

You can use the code below for from the script assembly:


var scriptFile = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), true)
                         .Cast<AssemblyDescriptionAttribute>()
                         .First()
                         .Description;

The full description is her:  http://www.csscript.net/help/Environment.html 

Tarmo Pikaro

unread,
Nov 24, 2012, 2:40:35 PM11/24/12
to cs-s...@googlegroups.com, osh...@gmail.com
Hi !

Ok, this seems to work, however - only for main module.

If I have coombination like: 
hello.cs, which calls
hello2.cs 

In hello2.cs I can get only hello.cs name. I've used all methods used in ReflectScript.cs.

Tarmo Pikaro

unread,
Nov 24, 2012, 4:51:33 PM11/24/12
to cs-s...@googlegroups.com, osh...@gmail.com
Hmmm...

Furthermore - I still miss System.Diagnostics.StackTrace - since it's possible that I have some failed test case, and need to report file name and line number.

How difficult it's to add such support ?

Oleg Shilo

unread,
Nov 25, 2012, 4:43:10 AM11/25/12
to cs-s...@googlegroups.com
As per my previous post  System.Diagnostics.StackTrace provided not by CS-Script but by CLR thus it is already (and always) available.

Tarmo Pikaro

unread,
Nov 25, 2012, 8:08:41 AM11/25/12
to cs-s...@googlegroups.com

Could you write a simple example of one script loading another script with stacktrace functional ?

I've understood that it's possible -  by modifying Samples\Hosting\Debugging.cs - but what if I wanted to have
starter.cs / static Main - works without filename/line info
main.cs / static Main - works with filename/line info

You're proposed to use CSScript.Load - and I have tried to write something like:

using System;
using CSScriptLibrary;

public class Host
{
    static void Main(string[] args)
    {
        try{
            new AsmHelper(CSScript.Load("main.cs", null, true)).GetStaticMethod().Invoke(args);
        }catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

But it does not work  - exception "Index was outside the bounds of the array."

Oleg Shilo

unread,
Nov 26, 2012, 6:27:06 AM11/26/12
to cs-s...@googlegroups.com
> But it does not work  - exception "Index was outside the bounds of the array." 
Cannot comment as I do not know the main.cs content. 


It prints the stack info for both first.cs and second.cs. Except lambdas of course.
Tarmo Pikaro.7z

Tarmo Pikaro

unread,
Nov 26, 2012, 3:07:50 PM11/26/12
to cs-s...@googlegroups.com, osh...@gmail.com
Hi !

Thanks, it looks like one step forward.
But it's so typical of me to shorten code - so I've tried to restart code using recursive function call to scripting library itself - like this:

using CSScriptLibrary;
using System;
using System.Windows.Forms;
using System.Linq;                      //.Cast
using System.Diagnostics;               //StackFrame
using System.Reflection;               

class Script
{
[STAThread]
static public void Main(string[] args)
{
        StackFrame sf = new System.Diagnostics.StackTrace(true).GetFrame(0);
        if( sf.GetFileName() == null )
        {
            String fileName = Assembly.GetExecutingAssembly()
                    .GetCustomAttributes(typeof(AssemblyDescriptionAttribute), true)
                    .Cast<System.Reflection.AssemblyDescriptionAttribute>().First().Description;

            Console.WriteLine("Restarting '" + fileName + "'");

            var Method = CSScript.Load(fileName, null, true).GetStaticMethod();
            Method();
        }

        Console.WriteLine( sf.GetFileName() + "(" + sf.GetFileLineNumber() + "): Stack frame available"  );
}
}

Concludes in exception:
Restarting 'C:\Projects\TestSuite\css\host.cs'

Error: Specified file could not be executed.

System.UnauthorizedAccessException: Access to the path 'C:\Users\<login>\AppData\Local\Temp\CSSCRIPT\Cache\1818316916\host.cs.compiled' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.Delete(String path)
   at csscript.CSExecutor.Compile(String scriptFileName)
   at csscript.CSExecutor.Compile(String scriptFile, String assemblyFile, Boolean debugBuild)
   at CSScriptLibrary.CSScript.LoadWithConfig(String scriptFile, String assemblyFile, Boolean debugBuild, Settings scriptSettings, String compilerOptions, String[] refAssemblies)
   at CSScriptLibrary.CSScript.Load(String scriptFile, String assemblyFile, Boolean debugBuild, String[] refAssemblies)
   at Script.Main(String[] args)


I could help you fixing it if you want, you need to tell me bit more details. :-)

Oleg Shilo

unread,
Nov 26, 2012, 6:31:25 PM11/26/12
to cs-s...@googlegroups.com
The problem is caused by the fact that you are trying to er-start the script while it is still loaded (locked) in the memory.

The easier solution would be to obtain the host script assembly (Assembly.GetExecutingAssembly()) and execute it not as a script but as an assembly (AppDomain.Execute(assembly)). 

Alternatively, if it is important to execute the script as a script, you may want to avoid the compiled script naming collisions by manually allocating the names. 

CSScript.Load(fileName, <the absolutely unique file name>, true).GetStaticMethod(); 


On Tue, Nov 27, 2012 at 7:07 AM, Tarmo Pikaro <tap...@yahoo.com> wrote:
rojects\TestSuite\css\host.cs'

Reply all
Reply to author
Forward
0 new messages