utils
Various utility functions.
Various utility functions.
Version: string
A string corresponding to the version.
Component uses semantic versioning (see https://semver.org).
function is_compatible(requiredVersionStr) {
let requiredVersion = requiredVersionStr.split('.');
let currentVersion = utils.Version.split('.'); // e.g. 0.1.0-alpha.2
if (currentVersion.length > 3) {
currentVersion.length = 3; // We need only numbers
}
for(let i = 0; i< currentVersion.length; ++i) {
if (currentVersion[i] != requiredVersion[i]) {
return currentVersion[i] > requiredVersion[i];
}
}
return true;
}
let requiredVersionStr = '1.0.0';
if (!is_compatible(requiredVersionStr)) {
fb.ShowPopupMessage(`This script requires v${requiredVersionStr}. Current component version is v${utils.Version}.`);
}
CheckComponent(name, is_dll)
Checks the availability of foobar2000 component.
| Name | Type | Description |
|---|---|---|
name | string | |
is_dll = trueoptional | boolean | If true, method checks filename as well as the internal name. |
booleanconsole.log(utils.CheckComponent("foo_playcount", true));
CheckFont(name)
Check if the font is installed.
Note: it cannot detect fonts loaded by foo_ui_hacks. However, gdi.Font can use those fonts.
| Name | Type | Description |
|---|---|---|
name | string | Can be either in English or the localised name in your OS. |
booleanColourPicker(window_id, default_colour)
Opens system colour picker dialog window (with some additional controls).
| Name | Type | Description |
|---|---|---|
window_id | number | Native window handle (HWND) to use as the dialog owner. Pass 0 to use the default foobar2000 window. |
default_colour | number | Color in ARGB format |
number — Chosen color in ARGB format or default_colour if cancelled
ConvertToAscii(str)
Converts string from UTF-8 to ASCII.
| Name | Type | Description |
|---|---|---|
str | string |
stringCopyFile(from, to, overwrite)
Copies a file.
| Name | Type | Description |
|---|---|---|
from | string | |
to | string | |
overwrite = trueoptional | boolean |
booleanCopyFolder(from, to, overwrite, recur)
Copies a folder.
| Name | Type | Description |
|---|---|---|
from | string | |
to | string | |
overwrite = trueoptional | boolean | |
recur = trueoptional | boolean |
booleanCRC32(str)
Calculates CRC32 value for string
| Name | Type | Description |
|---|---|---|
str | string | input string |
number — CRC32 value for input string. If string is empty returns 0
CRC32FromFile(path)
Calculates CRC32 value for file content
| Name | Type | Description |
|---|---|---|
path | string | input file path |
number — CRC32 value for input file content. If it was an error while reading file or file is empty returns 0
CreateFolder(path)
Creates a folder.
| Name | Type | Description |
|---|---|---|
path | string |
booleanDetectCharset(path)
Detect the codepage of the file.
Note: detection algorithm is probability based (unless there is a UTF BOM), i.e. even though the returned codepage is the most likely one, there's no 100% guarantee it's the correct one.\n Performance note: detection algorithm is quite slow, so results should be cached as much as possible.
| Name | Type | Description |
|---|---|---|
path | number | Path to file |
number — Codepage number on success, 0 if codepage detection failed
DownloadFileAsync(url, path)
Downloads file from specified URL to save file path. Result of asyncronous operation can be found in callback on_download_file_done
| Name | Type | Description |
|---|---|---|
url | string | File URL |
path | string | Save file path |
utils.DownloadFileAsync("https://lastfm.freetls.fastly.net/i/u/770x0/0be145cbf80930684d41ad524fe53768.jpg", "z:\\blah.jpg");
function on_download_file_done(path, success, error_text) {
console.log(path, success, error_text);
}
EditTextFile(path)
Edit a text file with the default text editor.
Default text editor can be changed via Edit button on the main tab of window.ShowConfigureV2.
| Name | Type | Description |
|---|---|---|
path | number | Path to file |
FileExists(path)
| Name | Type | Description |
|---|---|---|
path | number | Path to file |
boolean — true, if file exists.
FilePicker(title, default_path, filter, mode)
Opens system file picker dialog window
| Name | Type | Description |
|---|---|---|
title = undefinedoptional | string | Title of dialog. If empty it will be the title by system default |
default_path = undefinedoptional | string | Default file path to choose. If only path without file name is specified it will open specified folder |
filter = undefinedoptional | string | Files filter in form (for ex.): "Image files (*.jpg;*.png;*.bmp)|*.jpg;*.png;*.bmp|All files (*.*)|*.*" |
mode = 0optional | string | File dialog mode. 0 - open, 1 - save |
string — Chosen file path. If dialog is cancelled returns empty string
FileTest(path, mode)
Various utility functions for working with file.
Deprecated: use utils.DetectCharset, utils.FileExists, utils.GetFileSize, utils.IsDirectory, utils.IsFile and utils.SplitFilePath instead.
| Name | Type | Description |
|---|---|---|
path | string | |
mode | string | "chardet" - Detects the codepage of the given file. Returns a corresponding codepage number on success, 0 if codepage detection failed. |
*let arr = utils.FileTest("D:\\Somedir\\Somefile.txt", "split");
// arr[0] <= "D:\\Somedir\\" (always includes backslash at the end)
// arr[1] <= "Somefile"
// arr[2] <= ".txt"
FolderPicker(title, default_path)
Opens system folder picker dialog window
| Name | Type | Description |
|---|---|---|
title = undefinedoptional | string | Title of dialog. If empty it will be the title by system default |
default_path = undefinedoptional | string | Default folder path to choose |
string — Chosen folder path. If dialog is cancelled returns empty string
FontPicker(default_font, window_id)
Opens system font picker dialog window (with pixel size field extension).
| Name | Type | Description |
|---|---|---|
default_font = undefinedoptional | GdiFont | (or D2DFont if window.DrawMode=1) If specified, it will be selected in the dialog, otherwise the default system message font will be selected |
window_id = 0optional | number | Native window handle (HWND) to use as the dialog owner. Pass 0 to use the default foobar2000 window. |
?GdiFont — (or D2DFont if window.DrawMode=1) Chosen font or default_font if cancelled (if default_font is undefined returns null)
FormatDuration(seconds)
| Name | Type | Description |
|---|---|---|
seconds | number |
stringconsole.log(utils.FormatDuration(plman.GetPlaylistItems(plman.ActivePlaylist).CalcTotalDuration())); // 1wk 1d 17:25:30
FormatFileSize(bytes)
| Name | Type | Description |
|---|---|---|
bytes | number |
stringconsole.log(utils.FormatFileSize(plman.GetPlaylistItems(plman.ActivePlaylist).CalcTotalSize())); // 7.9 GB
GetAlbumArtAsync(window_id, handle, art_id, need_stub, only_embed, no_load)
Load art image for the track asynchronously.
| Name | Type | Description |
|---|---|---|
window_id | number | unused |
handle | FbMetadbHandle | |
art_id = 0optional | number | See AlbumArtId enum |
need_stub = trueoptional | boolean | |
only_embed = falseoptional | boolean | |
no_load = falseoptional | boolean | If true, "image" parameter will be null in on_get_album_art_done callback. |
GetAlbumArtAsyncV2(window_id, handle, art_id, need_stub, only_embed, no_load)
Load art image for the track asynchronously.
Returns a Promise object, which will be resolved when art loading is done.
| Name | Type | Description |
|---|---|---|
window_id | number | unused |
handle | FbMetadbHandle | |
art_id = 0optional | number | See AlbumArtId enum |
need_stub = trueoptional | boolean | If true, will return a stub image from |
only_embed = falseoptional | boolean | If true, will only try to load the embedded image. |
no_load = falseoptional | boolean | If true, then no art loading will be performed and only path to art will be returned in ArtPromiseResult. |
Promise.<ArtPromiseResult>GetAlbumArtEmbedded(rawpath, art_id)
Load embedded art image for the track.
Performance note: consider using utils.GetAlbumArtAsync or utils.GetAlbumArtAsyncV2 if there are a lot of images to load.
| Name | Type | Description |
|---|---|---|
rawpath | string | Path to track file |
art_id = 0optional | number | See AlbumArtId enum |
GdiBitmap — (or D2DBitmap if window.DrawMode == 1)
let img = utils.GetAlbumArtEmbedded(fb.GetNowPlaying().RawPath, 0);
GetAlbumArtV2(handle, art_id, need_stub)
Load art image for the track.
Performance note: consider using utils.GetAlbumArtAsync or utils.GetAlbumArtAsyncV2 if there are a lot of images to load.
| Name | Type | Description |
|---|---|---|
handle | FbMetadbHandle | |
art_id = 0optional | number | See AlbumArtId enum |
need_stub = trueoptional | boolean |
GdiBitmap — (or D2DBitmap if window.DrawMode == 1)
GetClipboardText()
string — Returns an empty string if clipboard contents are not text.
GetCountryFlag(country_or_code)
Returns string code for display country flag with "Twemoji Mozilla" font
ATTENTION! Country flags are displayed correctly only in Direct2D draw mode (window.DrawMode == 1); GDI+ does not render "Twemoji Mozilla" color glyphs.
| Name | Type | Description |
|---|---|---|
country_or_code | string | Case is not important. You can supply the code or full name. A few examples (full list see in the EXAMPLE file): |
string — Country string code
GetFileSize(path)
| Name | Type | Description |
|---|---|---|
path | string |
number — File size, in bytes
GetLastModified(path)
Gets "last modified" attribute for file
| Name | Type | Description |
|---|---|---|
path | string |
number — UNIX-time (seconds)
GetPackageInfo(package_id)
Get information about a package with the specified id.
| Name | Type | Description |
|---|---|---|
package_id | string | Can be obtained by window.ScriptInfo |
?JsPackageInfo — null if not found, package information otherwise
GetPackagePath(package_id)
Get path to a package directory with the specified id.
Throws exception if package is not found.
Deprecated: use utils.GetPackageInfo instead.
| Name | Type | Description |
|---|---|---|
package_id | string | Can be obtained by window.ScriptInfo |
stringGetSysColour(index)
| Name | Type | Description |
|---|---|---|
index | number | https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor |
number — 0 if failed
let splitter_colour = utils.GetSysColour(15);
GetSystemMetrics(index)
| Name | Type | Description |
|---|---|---|
index | number | https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor |
number — 0 if failed
Glob(pattern, exc_mask, inc_mask)
Retrieves filepaths that match the supplied pattern.
| Name | Type | Description |
|---|---|---|
pattern | string | For the path, you can use the * and ? wildcards for any intermediate directory and for the file name. |
exc_mask = 0x10optional | number | Mask to exclude files. Default is FILE_ATTRIBUTE_DIRECTORY. See flags like FILE_ATTRIBUTE_NORMAL etc. |
inc_mask = 0xffffffffoptional | number | Mask to include files |
Array<string>let arr = utils.Glob("C:\\*.*");
let arr2 = utils.Glob(fb.ProfilePath + 'image*\\album?\\*.jpg');
HTTPRequestAsync(type, url, user_agent_or_headers, post_data)
Does HTTP request of specified type to URL with optional user headers and post data
| Name | Type | Description |
|---|---|---|
type | number | Use 0 for GET, 1 for POST. |
url | number | |
user_agent_or_headers = ""optional | string | can be a string specifying the user agent, or a stringified JSON object specifying user HTTP request headers (see examples) |
post_data = ""optional | string | This is ignored for GET requests and can be omitted. It is required for POST requests. It could be form data or a stringified JSON object/array. |
number — a unique task_id which is used as the first argument in the on_http_request_done callback.
When making a POST request, you should set a Content-Type header. Valid values could be application/json or application/x-www-form-urlencoded.
let headers = JSON.stringify({
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0',
'Referer' : 'https://www.last.fm',
});
let url = 'https://www.last.fm/music/Madonna/+images';
let task_id = utils.HTTPRequestAsync(0, url, headers);
function on_http_request_done(task_id, success, response_text, status, content_type)
{
console.log("status = ", status, "response_text = ", response_text);
}
InputBox(window_id, prompt, caption, default_val, error_on_cancel, help_text)
| Name | Type | Description |
|---|---|---|
window_id | number | Native window handle (HWND) to use as the dialog owner. Pass 0 to use the default foobar2000 window. |
prompt | string | |
caption | string | |
default_val = ''optional | string | |
error_on_cancel = falseoptional | boolean | If set to true, use try/catch like Example2. |
help_text = ''optional | string | If not empty, a Help button will show in the dialog. If help_text begins with "http://" or "https://", it will launch a web browser otherwise it will open a popup window containing the text |
string// With "error_on_cancel" not set (or set to false), cancelling the dialog will return "default_val".
let username = utils.InputBox(0, "Enter your username", "Spider Monkey Panel", "");// Using Example1, you can't tell if OK or Cancel was pressed if the return value is the same
// as "default_val". If you need to know, set "error_on_cancel" to true which throws a script error
// when Cancel is pressed.
let username = "";
try {
username = utils.InputBox(0, "Enter your username", "Spider Monkey Panel", "", true);
// OK was pressed.
} catch(e) {
// Dialog was closed by pressing Esc, Cancel or the Close button.
}
IsDirectory(path)
| Name | Type | Description |
|---|---|---|
path | string |
boolean — true, if location exists and it's a directory
IsFile(path)
| Name | Type | Description |
|---|---|---|
path | string |
boolean — true, if location exists and it's a file
IsKeyPressed(vkey)
| Name | Type | Description |
|---|---|---|
vkey | number | See https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes. |
booleanListFonts(mode)
Gets system font collection array filled up by font families' names.
| Name | Type | Description |
|---|---|---|
mode = 0optional | number | 0 - Auto, 1 - GDI fonts, 2 - DirectWrite fonts |
Array<string> — array of font family names
MapString(text, lcid, flags)
| Name | Type | Description |
|---|---|---|
text | string | |
lcid | string | |
flags | number | defined in Flags, like LCMAP_LOWERCASE |
stringMD5(str)
Calculates MD5 for string
| Name | Type | Description |
|---|---|---|
str | string | input string |
string — MD5 value for input in hex format string. If input string is empty returns "d41d8cd98f00b204e9800998ecf8427e"
MD5FromFile(path)
Calculates MD5 value for file content
| Name | Type | Description |
|---|---|---|
path | string | input file path |
string — MD5 value for input file content in hex format string. If it was an error while reading file returns empty string. If file is empty returns "d41d8cd98f00b204e9800998ecf8427e"
MessageBox(msg, title, buttons, icon, default_button, help_text)
Shows system message box with specified parameters
| Name | Type | Description |
|---|---|---|
msg | string | |
title = "JSplitter"optional | string | |
buttons = MessageBoxButtons.OKoptional | MessageBoxButtons | |
icon = MessageBoxIcon.Informationoptional | MessageBoxIcon | See MessageBoxIcon |
default_button = MessageBoxDefaultButton.Button1optional | MessageBoxDefaultButton | |
help_text = ""optional | string | If not empty, a Help button will show in the dialog. If help_text begins with "http://" or "https://", it will launch a web browser otherwise it will open a popup window containing the text |
number — Result of message box. See DialogResult
ParseHtml(html)
Parses an HTML string and returns a lightweight DOM-like document.
This parser is backed by the native HTML parser. It does not use ActiveX, MSHTML, a browser engine, or external resource loading.
Notes:
- The input must be HTML text, not a file path.
- The returned API is DOM-like, but it is not a full browser DOM.
- CSS, layout, visibility, scripts, network loading, and browser events are not processed.
- innerText is currently an alias of textContent.
- The method returns null if the document could not be created.
| Name | Type | Description |
|---|---|---|
html | string | HTML source text. |
?HtmlDocument — Parsed document, or null on failure.
const doc = utils.ParseHtml("<html><body><p>Hello <b>world</b></p></body></html>");
if (doc) console.log(doc.body.textContent); // "Hello world"
PathWildcardMatch(pattern, str)
Check if the supplied string matches the pattern.
Using Microsoft MS-DOS wildcards match type. eg "*.txt", "abc?.tx?"
| Name | Type | Description |
|---|---|---|
pattern | string | |
str | string |
booleanReadBinaryFile(path)
Read a file as raw binary.
| Name | Type | Description |
|---|---|---|
path | string | Absolute file path |
Uint8Array — File bytes, or null if was an error
ReadINI(filename, section, key, default_val)
Note: this only returns up to 255 characters per value.
| Name | Type | Description |
|---|---|---|
filename | string | |
section | string | |
key | string | |
default_valoptional | string |
stringlet username = utils.ReadINI("e:\\my_file.ini", "Last.fm", "username");
ReadTextFile(filename, codepage)
Performance note: supply codepage argument if it is known, since codepage detection might take some time.
| Name | Type | Description |
|---|---|---|
filename | string | |
codepage = 65001optional | number | See Codepages.js. If codepage is 0, then automatic detection is performed. |
stringlet text = utils.ReadTextFile("E:\\some text file.txt");
ReadUTF8(path)
Returns a string. Will be empty if path doesn't exist or there was an error opening it.
For UTF8 files with or without BOM. If you're unsure about the file encoding, continue to use utils.ReadTextFile
| Name | Type | Description |
|---|---|---|
path | string |
stringRecyclePath(path)
Moves a file or directory to the Recycle Bin.
| Name | Type | Description |
|---|---|---|
path | string | path to a file or directory |
boolean — true on success, false otherwise
RemovePath(path)
Returns a number to indicate how many files/folders were removed.
May be 0 if the path did not exist or -1 if some other internal error occurred.
| Name | Type | Description |
|---|---|---|
path | string |
numberRenamePath(from, to)
Renames file or folder path.
| Name | Type | Description |
|---|---|---|
from | string | |
to | string |
booleanReplaceIllegalChars(str, strip_trailing_periods)
Uses the same modern unicode replacements as the foobar2000 converter/file operations.
| Name | Type | Description |
|---|---|---|
str | string | |
strip_trailing_periods = falseoptional | boolean | Set to true if str is a folder name. |
booleanRun(target, args, working_dir, verb, show, wait)
Runs a file, executable, URL, or document through the Windows shell.
This method uses ShellExecuteEx, so it supports shell verbs, file associations, URLs, and elevation through "runas".
Unlike RunCmdAsync, this method does not capture stdout or stderr and does not provide timeout handling.
If wait is true, the call blocks until the launched process exits, when a process handle is available.
| Name | Type | Description |
|---|---|---|
target | string | File, executable, URL, or document to run/open. |
argsoptional | string|string[] | Command line arguments. |
working_dir = ""optional | string | Working directory for the process. |
verb = ""optional | string | Shell verb to use. |
show = ShowWindow.Hideoptional | number | Requested window display mode. |
wait = falseoptional | boolean | Whether to wait for the launched process to exit. |
RunResult — Result object.
// Open a URL with the default browser.
const result = utils.Run("https://www.foobar2000.org");
console.log(result.OK);
console.log(result.Win32Error);
console.log(result.ShellCode);// Run a command and wait for its exit code.
const result = utils.Run(
"cmd.exe",
'/c "exit /b 7"',
"",
"",
ShowWindow.Hide,
true
);
console.log(result.OK); // false: process exited with a non-zero code
console.log(result.ExitCode); // 7: process exit code
console.log(result.Win32Error); // 0: process was started successfully// Run elevated.
const result = utils.Run(
"notepad.exe",
undefined,
"",
"runas",
ShowWindow.Show,
false
);
RunCmdAsync(app, args, working_dir, show, timeout_ms)
Runs an external process asynchronously.
Standard output and standard error are captured separately.
The method returns a task id immediately, and the result is delivered later to on_run_cmd_async_done.
Completion callbacks may arrive in a different order than the RunCmdAsync calls were made.
Use the returned task id to match the result with the original RunCmdAsync call.
If the process does not finish before timeout_ms, the whole process tree is terminated.
Pass 0 as timeout_ms to wait indefinitely.
| Name | Type | Description |
|---|---|---|
app | string | Full path or executable name to run. |
argsoptional | string|string[] | Command line arguments. |
working_dir = ""optional | string | Working directory for the process. |
show = ShowWindow.Hideoptional | number | Window display mode. |
timeout_ms = 0optional | number | Maximum time to wait for the process, in milliseconds. |
number — Task id of the asynchronous operation.
— Throws if called before foobar2000 is fully initialized, if args is invalid, or if the worker thread could not be started.
SetClipboardText(text)
| Name | Type | Description |
|---|---|---|
text | string |
SHA1(str)
Calculates SHA1 for string
| Name | Type | Description |
|---|---|---|
str | string | input string |
string — SHA1 value for input in hex format string. If input string is empty returns "da39a3ee5e6b4b0d3255bfef95601890afd80709"
SHA1FromFile(path)
Calculates SHA1 value for file content
| Name | Type | Description |
|---|---|---|
path | string | input file path |
string — SHA1 value for input file content in hex format string. If it was an error while reading file returns empty string. If file is empty returns "da39a3ee5e6b4b0d3255bfef95601890afd80709"
ShowHtmlDialog(window_id, code_or_path, options)
Displays an html dialog, rendered by IE engine.
Utilizes the latest non-Edge IE that you have on your system.
Dialog is modal (blocks input to the parent window while open).
Html code must be IE compatible, meaning:
data are limited to standard JavaScript objects: options.data may contain only the following types: JSON.stringify() and JSON.parse().toArray() inside html. Each element has same type limitations as options.dataoptions.datawindow.external inside the html dialog:dialogArguments - read-only value containing options.datadialogWindow - read-only native window handle (HWND) of the html dialog, represented as a number.window_id to JSplitter modal dialog functions to make the html dialog their owner, e.g. utils.ColourPicker, utils.FontPicker, utils.InputBox or utils.ShowHtmlDialog.| Name | Type | Description |
|---|---|---|
window_id | number | native window handle (HWND) to use as the dialog owner; pass 0 to use the default foobar2000 window |
code_or_path | string | Html code or file path. File path must begin with |
options = undefinedoptional | object | |
options.width = 250optional | number | Window width |
options.height = 100optional | number | Window height |
options.x = 0optional | number | Window horizontal position relative to desktop |
options.y = 0optional | number | Window vertical position relative to desktop |
options.center = trueoptional | boolean | If true and if options.x and options.y are not set, will center window relative to fb2k position. |
options.context_menu = falseoptional | boolean | If true, will enable right-click context menu. |
options.resizable = falseoptional | boolean | If true, will allow to resize the window. |
options.selection = falseoptional | boolean | If true, will allow to select everything (label texts, buttons and etc). |
options.scroll = falseoptional | boolean | If true, will display scrollbars. |
options.data = undefinedoptional | * | Will be saved in |
<caption>Dialog from file</caption>
utils.ShowHtmlDialog(0, `file://${fb.ComponentPath}samples/basic/html/PopupWithCheckBox.html`);
SplitFilePath(path)
| Name | Type | Description |
|---|---|---|
path | string |
Array<string> — An array of [directory, filename, filename_extension]
let arr = utils.SplitFilePath('D:\\Somedir\\Somefile.txt');
// arr[0] <= 'D:\\Somedir\\' (always includes backslash at the end)
// arr[1] <= 'Somefile'
// arr[2] <= '.txt'
WriteBinaryFile(path, data)
Write raw binary data to a file.
| Name | Type | Description |
|---|---|---|
path | string | Absolute file path |
data | Uint8Array | Bytes to write |
boolean — true on success
const img = gdi.Image(`${fb.ComponentPath}\\samples\\d2d\\images\\Field.jpg`);
let imgPixelData = img.GetPixelData();
utils.WriteBinaryFile("D:\\Field.bin", imgPixelData);
let rData = utils.ReadBinaryFile("D:\\Field.bin");
let rImg = gdi.CreateImageFromPixelData(rData, 2208, 1242);
function on_paint(gr) {
gr.DrawImage(rImg, 0, 0, img.Width, img.Height, 0, 0, img.Width, img.Height);
}
WriteINI(filename, section, key, val)
| Name | Type | Description |
|---|---|---|
filename | string | |
section | string | |
key | string | |
val | string |
booleanutils.WriteINI("e:\\my_file.ini", "Last.fm", "username", "Bob");
WriteTextFile(filename, content, write_bom)
Note: the parent folder must already exist. Note2: the file is written with UTF8 encoding.
| Name | Type | Description |
|---|---|---|
filename | string | |
content | string | |
write_bom = trueoptional | boolean |
boolean<caption>Default encoding</caption>
// write_bom missing but defaults to true, resulting file is UTF8-BOM
utils.WriteTextFile("z:\\1.txt", "test");<caption>UTF8 with BOM</caption>
utils.WriteTextFile("z:\\2.txt", "test", true);<caption>UTF8 without BOM</caption>
utils.WriteTextFile("z:\\3.txt", "test", false);