2

I am trying to call LinqPad query from C#. Unfortunately, the code below does not work; the result is null as if nothing got returned by the script. I don't see any example of how to do this online. Any direction would be appreciated.

This is the LinqPad code for the query. It is saved as a C# Statement:

string Main(string message)
{
    "testing".Dump();
    return message.ToUpper();
}

This is the code in C# code in a Visual Studio Project Console Application that attempts to call the query:

using System;

using LINQPad;


namespace ConsoleAppLinqPad
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string pathToQuery = @"C:\Users\synct\OneDrive\Documents\LINQPad Queries\";
            string script = "samplequery.linq";
            var wholePath = pathToQuery + script;

            using (var query = Util.Compile(wholePath))
            {
                var results = query.Run(QueryResultFormat.Text, "hello world").ReturnValueAsync.GetAwaiter();

                while (!results.IsCompleted)
                    ;


                var result = results.GetResult();
                Console.WriteLine(result.Dump());  // prints "HELLO WORLD?"
                
            }

            Console.ReadKey();
        }
    }
}
Erçin Dedeoğlu
  • 4,950
  • 4
  • 49
  • 69
Ivan
  • 7,448
  • 14
  • 69
  • 134
  • What do you mean "the code below does not work"? – David L Dec 13 '21 at 19:40
  • I updated the original post. If there is a working sample I would love to see it. – Ivan Dec 13 '21 at 19:42
  • Are you aware of [lprun](https://www.linqpad.net/lprun.aspx)? – Crowcoder Dec 13 '21 at 20:14
  • Yes, but how is that different than what I am trying to do here? I don't reallly want to instantiate a process unless the above strategy doesn't work – Ivan Dec 13 '21 at 20:34
  • Running a .NET console app will create a process too. I don't know your requirements, but if you're just trying to run a LINQPad script then lprun.exe is the most straightforward. – Crowcoder Dec 13 '21 at 21:02
  • I see. Is there an example of how to instantiate lprun and pass it a query to execute, then gather the result from C#? – Ivan Dec 13 '21 at 21:06
  • 1
    The doc I linked to has all I know about it and more. I guess you could use Process.Start and redirect output but it seems a round-about way to execute a script. I suppose it is not practical to just put the code in a proper .NET application? – Crowcoder Dec 13 '21 at 21:12
  • I have provided an example of the lprun usage in my answer. Please have a look. – Matt Sep 02 '22 at 06:10
  • https://stackoverflow.com/q/2699466/5045688 – Alexander Petrov Sep 02 '22 at 10:39

1 Answers1

2

There is a LPRun7-x64.exe shipped with LinqPad (ARM64 and x86 versions are available as well) which allows to run LinqPad from a console. But you can also run it from a process.

With the example below you could run your samplequery.linq like:

string pathToQuery = @"C:\Users\synct\OneDrive\Documents\LINQPad Queries\";
string script = "samplequery.linq";
RunLpQuery(@$"{pathToQuery}{script}");

Example:

void Main()
{
    RunLpQuery(@$"{AppPath}\Hello.linq");
}

public string AppPath =>
#if LINQPAD
    System.IO.Path.GetDirectoryName(Util.CurrentQueryPath);
#else
    System.IO.Path.GetDirectoryName(Assembly.GetAssembly(this.GetType()).Location);
#endif

// Linqpad 4+5: "LPRun.exe"
// LinqPad 6:   "LPRun6.exe"
// Linqpad 7:   "LPRun7-x64.exe"  
public const string LpRunName = "LPRun7-x64.exe";

object RunLpQuery(string query)
#if LINQPAD
    => Util.Run(query, QueryResultFormat.Html).Dump();
#else
    => StartProcess(@$"{Util.LINQPadFolder}\{LpRunName}", AppPath, query);
#endif

bool StartProcess(string fileName, string workingDir, string arguments,
                  bool hidden = false)
{
    var p = new Process();
    var args = p.StartInfo;
    if (hidden)
    {
        args.CreateNoWindow = true; args.UseShellExecute = false; // runs hidden
    }
    args.FileName = fileName;
    args.WorkingDirectory = workingDir;
    args.Arguments = arguments;
    var result = p.Start();
    p.WaitForExit();
    return result;
}

Hello.linq:

void Main()
{
    for (int i = 0; i < 5; i++)
    {
        "Hello World!".Dump(); Thread.Sleep(500);
    }   
}

Note that the example uses conditional compilation: Through #if LINQPAD statements it can run directly inside of LinqPad itself, showing the output of the called Hello example in the result windows, or outside in a Visual Studio project.


Details about the parameters for lprun can be found here. And if you just want to use LinqPad's extensions in the context of your VS project, then have a look there.

Matt
  • 25,467
  • 18
  • 120
  • 187