コード例 #1
0
ファイル: Program.cs プロジェクト: alexfordc/Au
    //[STAThread] //we use TrySetApartmentState instead
    static void Main(string[] args)
    {
        string asmFile, fullPathRefs; int pdbOffset, flags;

        if (args.Length != 1)
        {
            return;
        }
        string pipeName = args[0];         //if(!pipeName.Starts(@"\\.\pipe\Au.Task-")) return;

        int nr = 0;

#if false
        //With NamedPipeClientStream faster by 1 ms, because don't need to JIT. But problems:
        //1. Loads System and System.Core immediately, making slower startup.
        //2. This process does not end when editor process ended, because then Connect spin-waits for server created.
        using (var pipe = new NamedPipeClientStream(".", pipeName.Substring(9), PipeDirection.In)) {
            pipe.Connect();
            var b = new byte[10000];
            nr = pipe.Read(b, 0, b.Length);
        }
#else
        //APerf.First();
        //_PrepareTest();
        //APerf.NW();

        for (int i = 0; i < 3; i++)
        {
            if (Api.WaitNamedPipe(pipeName, i == 2 ? -1 : 100))
            {
                break;
            }
            if (Marshal.GetLastWin32Error() != Api.ERROR_SEM_TIMEOUT)
            {
                return;
            }
            //APerf.First();
            switch (i)
            {
            case 0: _Prepare1(); break;             //~25 ms with cold CPU
                //case 1: _Prepare2(); break; //~15 ms with cold CPU
            }
            //APerf.NW();
        }
        //APerf.First();
        using (var pipe = Api.CreateFile(pipeName, Api.GENERIC_READ, 0, default, Api.OPEN_EXISTING, 0)) {
            if (pipe.Is0)
            {
                ADebug.PrintNativeError_(); return;
            }
            //APerf.Next();
            int size; if (!Api.ReadFile(pipe, &size, 4, out nr, default) || nr != 4)
            {
                return;
            }
            //APerf.Next();
            if (!Api.ReadFileArr(pipe, out var b, size, out nr) || nr != size)
            {
                return;
            }
            //APerf.Next();

            //ADebug.PrintLoadedAssemblies(true, true);
            //APerf.First();

            var a = Au.Util.Serializer_.Deserialize(b);
            ATask.Init_(ATRole.MiniProgram, a[0]);
            asmFile = a[1]; pdbOffset = a[2]; flags = a[3]; args = a[4]; fullPathRefs = a[5];
            string wrp = a[6]; if (wrp != null)
            {
                Environment.SetEnvironmentVariable("ATask.WriteResult.pipe", wrp);
            }
            AFolders.Workspace = (string)a[7];
        }
#endif
        //APerf.Next();

        bool mtaThread = 0 != (flags & 2);         //app without [STAThread]
        if (mtaThread == s_isSTA)
        {
            _SetComApartment(mtaThread ? ApartmentState.MTA : ApartmentState.STA);
        }

        if (0 != (flags & 4))
        {
            Api.AllocConsole();                          //meta console true
        }
        //if(0 != (flags & 1)) { //hasConfig
        //	var config = asmFile + ".config";
        //	if(AFile.ExistsAsFile(config, true)) AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", config);
        //}

        if (s_hook == null)
        {
            _Hook();
        }

        //APerf.Next();
        try { RunAssembly.Run(asmFile, args, pdbOffset, fullPathRefs: fullPathRefs); }
        catch (Exception ex) { AOutput.Write(ex); }
        finally { s_hook?.Dispose(); }
    }