IronLanguages / ironpython3

Implementation of Python 3.x for .NET Framework that is built on top of the Dynamic Language Runtime.
Apache License 2.0
2.48k stars 287 forks source link

The ipyc /out: option dose not change the output path of exe host #1785

Open wherewhere opened 6 months ago

wherewhere commented 6 months ago

Prerequisites

ipyc /out: option dose not change the output path of exe host.

Description

When I set the output to bin\Program with ipyc /out:bin/Program /main:Program.py, the Program.exe still output at the path which Program.py at. And the host get the Program.dll at bin/Program.dll, as I can not just copy the exe to bin. If I set the output path to an absolute path, I even can not move the program to another place...

public class PythonMain
{
    public static int Main()
    {
        try
        {
            string currentDirectory = Environment.CurrentDirectory;
            Environment.CurrentDirectory = new FileInfo(Assembly.GetEntryAssembly().Location).Directory.FullName;
            string fullPath = Path.GetFullPath("bin/Program.dll");
            Environment.CurrentDirectory = currentDirectory;
            return PythonOps.InitializeModuleEx(Assembly.LoadFile(fullPath), "__main__", null, ignoreEnvVars: false, null);
        }
        catch (Exception ex)
        {
            string currentDirectory = ex.Message;
            Console.WriteLine("Error occurred: {0}", currentDirectory);
            return -1;
        }
    }
}

So why not combined the host and dll just like JScript?

public class JScript Main
{
    [STAThread(/*Could not decode attribute arguments.*/)]
    public static void Main(string[] P_0)
    {
        GlobalScope globalScope = VsaEngine.CreateEngineAndGetGlobalScope(fast: true, new string[5] { "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime.InteropServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Reflection, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" });
        JScript 0 obj = new JScript 0(globalScope);
        globalScope.engine.PushScriptObject(obj);
        obj.Global Code();
        new JScript 1(globalScope).Global Code();
        globalScope.engine.PopScriptObject();
    }
}

To fixed that I must create a host by myself. I referenced to the dll so I can just get the assembly by Assembly.LoadFrom.

using IronPython.Runtime.Operations;
using System.Reflection;
using System;

try
{
    return PythonOps.InitializeModuleEx(Assembly.LoadFrom("Samples.PY.dll"), "__main__", null, ignoreEnvVars: false, null);
}
catch (Exception ex)
{
    Console.WriteLine("Error occurred: {0}", ex.Message);
    return -1;
}

https://github.com/wherewhere/MSBuild.Sdk.Extras/tree/main/Samples/Samples.PY.Host

Version Information

IronPython 3.4.1 (3.4.1.1000) [.NETFramework,Version=v4.6.2 on .NET Framework 4.8.9181.0 (64-bit)]