Example #1
0
        /// <summary>
        /// Saves the Shortcut variable properties to the shortcut file.
        /// </summary>
        /// <exception cref="AuException">Failed to save .lnk file.</exception>
        /// <remarks>
        /// Creates parent folder if need.
        /// </remarks>
        public void Save()
        {
            if (_changedHotkey && !_isOpen && AFile.ExistsAsFile(_lnkPath))
            {
                _UnregisterHotkey(_lnkPath);
            }

            AFile.CreateDirectoryFor(_lnkPath);
            AuException.ThrowIfHresultNot0(_ipf.Save(_lnkPath, true), "*save");
        }
Example #2
0
        //This could be public, but then need to make IShellLink public. It is defined in a non-standard way. Never mind, it is not important.

        AShortcutFile(string lnkPath, uint mode)
        {
            _isl     = new Api.ShellLink() as Api.IShellLink;
            _ipf     = _isl as Api.IPersistFile;
            _lnkPath = lnkPath;
            if (mode != Api.STGM_WRITE && (mode == Api.STGM_READ || AFile.ExistsAsFile(_lnkPath)))
            {
                AuException.ThrowIfHresultNot0(_ipf.Load(_lnkPath, mode), "*open");
                _isOpen = true;
            }
        }
Example #3
0
        /// <summary>
        /// Opens or creates a database file.
        /// </summary>
        /// <param name="file">
        /// Database file. Can be:
        /// - Full path. Supports environment variables etc, see <see cref="APath.ExpandEnvVar"/>
        /// - ":memory:" - create a private, temporary in-memory database.
        /// - "" - create a private, temporary on-disk database.
        /// - Starts with "file:" - see sqlite3_open_v2 documentation in SQLite website.
        /// </param>
        /// <param name="flags">sqlite3_open_v2 flags, documanted in SQLite website. Default: read-write, create file if does not exist (and parent directory).</param>
        /// <param name="sql">
        /// SQL to execute. For example, one or more ;-separated PRAGMA statements to configure the database connection. Or even "CREATE TABLE IF NOT EXISTS ...".
        /// This function also always executes "PRAGMA foreign_keys=ON;PRAGMA secure_delete=ON;".
        /// </param>
        /// <exception cref="ArgumentException">Not full path.</exception>
        /// <exception cref="SLException">Failed to open database or execute sql.</exception>
        /// <remarks>
        /// Calls sqlite3_open_v2.
        /// <note>If a variable of this class is used by multiple threads, use <c>lock(variable) {  }</c> where need.</note>
        /// </remarks>
        public ASqlite(string file, SLFlags flags = SLFlags.ReadWriteCreate, string sql = null)
        {
            bool isSpec = file != null && (file.Length == 0 || file == ":memory:" || file.Starts("file:"));

            if (!isSpec)
            {
                file = APath.Normalize(file);
                if (flags.Has(SLFlags.SQLITE_OPEN_CREATE) && !AFile.ExistsAsFile(file, true))
                {
                    AFile.CreateDirectoryFor(file);
                }
            }
            var r = SLApi.sqlite3_open_v2(AConvert.ToUtf8(file), ref _db, flags, null);

            if (r != 0)
            {
                Dispose();
                throw new SLException(r, "sqlite3_open " + file);
            }
            Execute("PRAGMA foreign_keys=ON;PRAGMA secure_delete=ON;" + sql);
        }
Example #4
0
        Bitmap _GetImage(string file, IconGetFlags giFlags, Func <Bitmap> callback, Action <Bitmap, object> autoUpdate, object auParam, bool auDispose)
        {
            bool cached = true;

            lock (this) {
                Bitmap R = null;

                //is in memory cache?
                if (_table == null)
                {
                    _table = new Hashtable(StringComparer.OrdinalIgnoreCase);
                }
                else
                {
                    R = _table[file] as Bitmap;
                }

                if (R == null)
                {
                    //is in file cache?
                    try {
                        if (_x == null && AFile.ExistsAsFile(_cacheFile))
                        {
                            _x = AExtXml.LoadElem(_cacheFile);
                            if (_iconSize != _x.Attr("size", 0) || ADpi.BaseDPI != _x.Attr("dpi", 0))
                            {
                                _x = null;
                                ADebug.Print("info: cleared icon cache");
                            }

                            //FUTURE: Delete unused entries. Maybe try to auto-update changed icons.
                            //	Not very important, because there is ClearCache.
                        }
                        if (_x != null)
                        {
                            var x = _x.Elem("i", "name", file, true);
                            if (x != null)
                            {
                                using var ms = new MemoryStream(Convert.FromBase64String(x.Value), false);
                                R            = new Bitmap(ms);
                            }
                        }
                    }
                    catch (Exception ex) {
                        ADebug.Print(ex.Message);
                    }

                    if (R != null)
                    {
                        _table[file] = R;                                //add to memory cache
                    }
                    else if (_LoadImage(out R, file, giFlags, callback)) //get file icon
                    {
                        _AddImage(file, R, false);                       //add to file cache and memory cache
                        cached = false;
                    }
                }

                //auto-update
                if (cached && autoUpdate != null)
                {
                    var d = new _AUData()
                    {
                        cache       = this, oldImage = R, file = file, callback = callback,
                        autoUpdated = autoUpdate, auParam = auParam, giFlags = giFlags, canDispose = auDispose,
                    };
                    _AutoUpdateAdd(d);
                }

                return(R);
            }
        }
Example #5
0
        /// <summary>
        /// Executes assembly in this thread.
        /// Handles exceptions.
        /// </summary>
        /// <param name="asmFile">Full path of assembly file.</param>
        /// <param name="args">To pass to Main.</param>
        /// <param name="pdbOffset">0 or offset of portable PDB in assembly file.</param>
        /// <param name="flags"></param>
        /// <param name="fullPathRefs">Paths of assemblies specified using full path.</param>
        public static void Run(string asmFile, string[] args, int pdbOffset, RAFlags flags = 0, string fullPathRefs = null)
        {
            ADebug.PrintIf(pdbOffset == 0, "pdbOffset 0");

            bool inEditorThread       = 0 != (flags & RAFlags.InEditorThread);
            bool findLoaded           = inEditorThread;
            _LoadedScriptAssembly lsa = default;
            Assembly asm = findLoaded ? lsa.Find(asmFile) : null;

            if (asm == null)
            {
#if true
                //var p1 = APerf.Create();
                var alc = System.Runtime.Loader.AssemblyLoadContext.Default;
                //SHOULDDO: try to unload. It seems AssemblyLoadContext supports it. Not tested. I guess it would create more problems than is useful.
                //p1.Next();
                using (var stream = AFile.WaitIfLocked(() => File.OpenRead(asmFile))) {
                    //p1.Next();
                    if (pdbOffset > 0)
                    {
                        var b = new byte[pdbOffset];
                        stream.Read(b, 0, b.Length);
                        using var msAsm = new MemoryStream(b);
                        b = new byte[stream.Length - pdbOffset];
                        stream.Read(b, 0, b.Length);
                        using var msDeb = new MemoryStream(b);
                        //p1.Next('f');
                        asm = alc.LoadFromStream(msAsm, msDeb);
                        //p1.Next();
                    }
                    else
                    {
                        asm = alc.LoadFromStream(stream);
                    }
                }
                //p1.NW();
                //APerf.Next('a');

                if (fullPathRefs != null)
                {
                    var fpr = fullPathRefs.SegSplit("|");
                    alc.Resolving += (System.Runtime.Loader.AssemblyLoadContext alc, AssemblyName an) => {
                        //AOutput.Write(an, an.Name, an.FullName);
                        foreach (var v in fpr)
                        {
                            var s1    = an.Name;
                            int iName = v.Length - s1.Length - 4;
                            if (iName <= 0 || v[iName - 1] != '\\' || !v.Eq(iName, s1, true))
                            {
                                continue;
                            }
                            if (!AFile.ExistsAsFile(v))
                            {
                                continue;
                            }
                            //try {
                            return(alc.LoadFromAssemblyPath(v));
                            //} catch(Exception ex) { ADebug.Print(ex.ToStringWithoutStack()); break; }
                        }
                        return(null);
                    };
                }

                //ADebug.PrintLoadedAssemblies(true, true);

                //AOutput.Write(asm);
#else
                byte[] bAsm, bPdb = null;
                using (var stream = AFile.WaitIfLocked(() => File.OpenRead(asmFile))) {
                    bAsm = new byte[pdbOffset > 0 ? pdbOffset : stream.Length];
                    stream.Read(bAsm, 0, bAsm.Length);
                    try {
                        if (pdbOffset > 0)
                        {
                            bPdb = new byte[stream.Length - pdbOffset];
                            stream.Read(bPdb, 0, bPdb.Length);
                        }
                        else
                        {
                            var s1 = Path.ChangeExtension(asmFile, "pdb");
                            if (AFile.ExistsAsFile(s1))
                            {
                                bPdb = File.ReadAllBytes(s1);
                            }
                        }
                    }
                    catch (Exception ex) { bPdb = null; ADebug.Print(ex); }                    //not very important
                }
                //APerf.Next('f');
                //APerf.First();
                asm = Assembly.Load(bAsm, bPdb);
#endif
                //APerf.Next('A');
                //APerf.NW(); //without AV 7 ms. With Windows Defender 10 ms, but first time 20-900 ms.
                if (findLoaded)
                {
                    lsa.Add(asmFile, asm);
                }

                //never mind: it's possible that we load a newer compiled assembly version of script than intended.
            }

            try {
                var entryPoint = asm.EntryPoint ?? throw new InvalidOperationException("assembly without entry point (function Main)");

                bool useArgs = entryPoint.GetParameters().Length != 0;
                if (useArgs)
                {
                    if (args == null)
                    {
                        args = Array.Empty <string>();
                    }
                }

                //APerf.Next('1');
                if (!inEditorThread)
                {
                    Util.Log_.Run.Write("Task started.");
                }

                //APerf.Next('2');
                if (useArgs)
                {
                    entryPoint.Invoke(null, new object[] { args });
                }
                else
                {
                    entryPoint.Invoke(null, null);
                }

                if (!inEditorThread)
                {
                    Util.Log_.Run.Write("Task ended.");
                }
            }
            catch (TargetInvocationException te) {
                var e = te.InnerException;

                if (!inEditorThread)
                {
                    Util.Log_.Run.Write($"Unhandled exception: {e.ToStringWithoutStack()}");
                }

                if (0 != (flags & RAFlags.DontHandleExceptions))
                {
                    throw e;
                }
                //AOutput.Write(e);
                AScript.OnHostHandledException(new UnhandledExceptionEventArgs(e, false));
            }

            //see also: TaskScheduler.UnobservedTaskException event.
            //	tested: the event works.
            //	tested: somehow does not terminate process even with <ThrowUnobservedTaskExceptions enabled="true"/>.
            //		Only when ADialog.Show called, the GC.Collect makes it to disappear but the process does not exit.
            //	note: the terminating behavior also can be set in registry or env var. It overrides <ThrowUnobservedTaskExceptions enabled="false"/>.
        }