diff --git a/HISTORY.md b/HISTORY.md index aa8cbac..fbe8f72 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # History +## SenkoWSH v4.2.0 +### 更新点 +- 変数の型名を取得する `System.typeOf` を追加 +- `SFile.prototype.searchFile` について引数に正規表現を入れるなどの改善、及び複数ファイルを探すような機能を追加 +- `SFile.prototype.move` のエラー処理を強化、詳細な動作仕様をメソッドの説明に記載 +- `SFile.prototype.renameTo` のエラー処理を強化、詳細な動作仕様をメソッドの説明に記載 + ## SenkoWSH v4.1.1 ### 更新点 - `SFile` の入力引数に `SFile` 型を入力するとエラーが発生する場合があったのを回避 diff --git a/build/SenkoWSH.d.ts b/build/SenkoWSH.d.ts index d387bef..db52737 100644 --- a/build/SenkoWSH.d.ts +++ b/build/SenkoWSH.d.ts @@ -1180,13 +1180,21 @@ declare class SFile { copy(file_obj: string | SFile): boolean; /** * ファイルの移動 - * @param {string|SFile} file_obj + * - 移動後の `this` は、移動後のファイルを指す + * - `this` がファイルの場合、ディレクトリを選択すると、ディレクトリ内へファイルを移動させます + * - `this` がファイルの場合、ファイルを選択すると、ディレクトリの移動かつファイル名を変更します + * - `this` がディレクトリの場合、指定したディレクトリへファイルを移動させるため、ディレクトリ名の変更は行えません + * + * @param {string|SFile} file_obj - 移動先のファイル名及びディレクトリ * @returns {boolean} */ move(file_obj: string | SFile): boolean; /** * ファイル名を変更 - * @param {string|SFile} file_obj + * - 変更後の `this` は、変更後のファイルを指す + * - 引数はフルパスを渡した場合でもファイル名のみ使用する + * + * @param {string|SFile} file_obj 変更後のファイル名 * @returns {boolean} */ renameTo(file_obj: string | SFile): boolean; @@ -1202,7 +1210,9 @@ declare class SFile { getName(): string; /** * 親フォルダの絶対パス - * URLなら最後にスラッシュをつけて返す + * - 通常のフォルダの場合は、最後の「`/`」は除去される + * - URLなら最後にスラッシュをつけて返す + * * @returns {string} */ getParent(): string; @@ -1393,11 +1403,13 @@ declare class SFile { getAllFiles(): SFile[]; /** * 指定した条件にあうファイルを探す - * 関数を指定する場合は、ファイル名とフルパスが引数に渡されます - * @param {string|SFile|function(string, string): boolean} file_obj - * @returns {SFile|null} + * - 関数を指定する場合は、ファイル名とフルパスが引数に渡されます + * + * @param {string|SFile|RegExp|function(SFile): boolean} file_obj + * @param {boolean} [is_all_file=false] trueで指定した場合は条件に合うファイルを複数見つけて配列で返す + * @returns {SFile|SFile[]|null} */ - searchFile(file_obj: string | SFile | ((...params: any[]) => any)): SFile | null; + searchFile(file_obj: string | SFile | RegExp | ((...params: any[]) => any), is_all_file?: boolean): SFile | SFile[] | null; /** * 圧縮する * - 圧縮後のファイル名の拡張子で圧縮したい形式を指定する @@ -1634,6 +1646,14 @@ declare class System { * @returns {any} */ static createByteArrayFromNumberArray(number_array: number[], offset?: number): any; + /** + * データの型を小文字の英字で返す + * - 配列であれば `array`、正規表現であれば `regexp` などを返します + * + * @param {any} x + * @returns {string} + */ + static typeOf(x: any): string; } /** diff --git a/build/SenkoWSH.js b/build/SenkoWSH.js index 91e9b80..7f9aca5 100644 Binary files a/build/SenkoWSH.js and b/build/SenkoWSH.js differ diff --git a/docs/class/src/senko/SFile.js~SFile.html b/docs/class/src/senko/SFile.js~SFile.html index dbec463..4c66181 100644 --- a/docs/class/src/senko/SFile.js~SFile.html +++ b/docs/class/src/senko/SFile.js~SFile.html @@ -803,8 +803,11 @@

SFile

-

親フォルダの絶対パス -URLなら最後にスラッシュをつけて返す

+

親フォルダの絶対パス

+
    +
  • 通常のフォルダの場合は、最後の「/」は除去される
  • +
  • URLなら最後にスラッシュをつけて返す
  • +
@@ -1222,6 +1225,12 @@

SFile

ファイルの移動

+
@@ -1280,6 +1289,10 @@

SFile

ファイル名を変更

+
@@ -1331,14 +1344,16 @@

SFile

- searchFile(file_obj: string | SFile | function(prm1: string, prm2: string): boolean): SFile | null + searchFile(file_obj: string | SFile | RegExp | function(prm1: SFile): boolean, is_all_file: boolean): SFile | SFile[] | null

-

指定した条件にあうファイルを探す -関数を指定する場合は、ファイル名とフルパスが引数に渡されます

+

指定した条件にあうファイルを探す

+
    +
  • 関数を指定する場合は、ファイル名とフルパスが引数に渡されます
  • +
@@ -1574,7 +1589,7 @@

- source + source

@@ -1660,7 +1675,7 @@

- source + source

@@ -1716,7 +1731,7 @@

- source + source

@@ -1801,7 +1816,7 @@

- source + source

@@ -1863,7 +1878,7 @@

- source + source

@@ -1919,7 +1934,7 @@

- source + source

@@ -1998,7 +2013,7 @@

- source + source

@@ -2329,7 +2344,7 @@

- source + source

@@ -2459,7 +2474,7 @@

- source + source

@@ -2515,7 +2530,7 @@

- source + source

@@ -2571,7 +2586,7 @@

- source + source

@@ -2655,7 +2670,7 @@

- source + source

@@ -2711,7 +2726,7 @@

- source + source

@@ -2767,7 +2782,7 @@

- source + source

@@ -2842,7 +2857,7 @@

- source + source

@@ -2898,7 +2913,7 @@

- source + source

@@ -2954,15 +2969,18 @@

- source + source

-

親フォルダの絶対パス -URLなら最後にスラッシュをつけて返す

+

親フォルダの絶対パス

+
    +
  • 通常のフォルダの場合は、最後の「/」は除去される
  • +
  • URLなら最後にスラッシュをつけて返す
  • +
@@ -3011,7 +3029,7 @@

- source + source

@@ -3067,7 +3085,7 @@

- source + source

@@ -3123,7 +3141,7 @@

- source + source

@@ -3201,7 +3219,7 @@

- source + source

@@ -3257,7 +3275,7 @@

- source + source

@@ -3313,7 +3331,7 @@

- source + source

@@ -3369,7 +3387,7 @@

- source + source

@@ -3425,7 +3443,7 @@

- source + source

@@ -3481,7 +3499,7 @@

- source + source

@@ -3537,7 +3555,7 @@

- source + source

@@ -3593,7 +3611,7 @@

- source + source

@@ -3649,7 +3667,7 @@

- source + source

@@ -3709,7 +3727,7 @@

- source + source

@@ -3769,7 +3787,7 @@

- source + source

@@ -3777,6 +3795,12 @@

ファイルの移動

+
    +
  • 移動後の this は、移動後のファイルを指す
  • +
  • this がファイルの場合、ディレクトリを選択すると、ディレクトリ内へファイルを移動させます
  • +
  • this がファイルの場合、ファイルを選択すると、ディレクトリの移動かつファイル名を変更します
  • +
  • this がディレクトリの場合、指定したディレクトリへファイルを移動させるため、ディレクトリ名の変更は行えません
  • +
@@ -3793,7 +3817,8 @@

Params:

file_obj string | SFile - +

移動先のファイル名及びディレクトリ

+ @@ -3915,7 +3940,7 @@

- source + source

@@ -3923,6 +3948,10 @@

ファイル名を変更

+
    +
  • 変更後の this は、変更後のファイルを指す
  • +
  • 引数はフルパスを渡した場合でもファイル名のみ使用する
  • +
@@ -3939,7 +3968,8 @@

Params:

file_obj string | SFile - +

変更後のファイル名

+ @@ -3987,7 +4017,7 @@

- source + source

@@ -4065,19 +4095,21 @@

- searchFile(file_obj: string | SFile | function(prm1: string, prm2: string): boolean): SFile | null + searchFile(file_obj: string | SFile | RegExp | function(prm1: SFile): boolean, is_all_file: boolean): SFile | SFile[] | null - source + source

-

指定した条件にあうファイルを探す -関数を指定する場合は、ファイル名とフルパスが引数に渡されます

+

指定した条件にあうファイルを探す

+
    +
  • 関数を指定する場合は、ファイル名とフルパスが引数に渡されます
  • +
@@ -4092,10 +4124,18 @@

Params:

file_obj - string | SFile | function(prm1: string, prm2: string): boolean + string | SFile | RegExp | function(prm1: SFile): boolean + + is_all_file + boolean +
  • optional
  • +
  • default: false
+

trueで指定した場合は条件に合うファイルを複数見つけて配列で返す

+ +
@@ -4106,7 +4146,7 @@

Return:

- + @@ -4142,7 +4182,7 @@

- source + source

@@ -4224,7 +4264,7 @@

- source + source

@@ -4303,7 +4343,7 @@

- source + source

@@ -4375,7 +4415,7 @@

- source + source

@@ -4454,7 +4494,7 @@

- source + source

@@ -4550,7 +4590,7 @@

- source + source

@@ -4606,7 +4646,7 @@

- source + source

diff --git a/docs/class/src/senko/System.js~System.html b/docs/class/src/senko/System.js~System.html index 5b0324e..effbbe9 100644 --- a/docs/class/src/senko/System.js~System.html +++ b/docs/class/src/senko/System.js~System.html @@ -963,6 +963,38 @@

System

+ + + + + @@ -2829,6 +2861,81 @@

+ +
+

+ public + static + + + + + typeOf(x: any): string + + + + source + +

+ + + + +

データの型を小文字の英字で返す

+
    +
  • 配列であれば array、正規表現であれば regexp などを返します
  • +
+
+ + + +
+

Params:

+

SFile | nullSFile | SFile[] | null
+
+ public + static + + + + +
+

+ + + + typeOf(x: any): string +

+
+
+ + +

データの型を小文字の英字で返す

+
    +
  • 配列であれば array、正規表現であれば regexp などを返します
  • +
+
+
+
+ +
+ + + + + + + + + + + + +
NameTypeAttributeDescription
xany
+
+
+ +
+

Return:

+ + + + + + + +
string
+
+
+
+ + + + + + + + + + + + + + + diff --git a/docs/coverage.json b/docs/coverage.json index 33bbc72..e94d0bd 100644 --- a/docs/coverage.json +++ b/docs/coverage.json @@ -1,7 +1,7 @@ { "coverage": "100%", - "expectCount": 187, - "actualCount": 187, + "expectCount": 188, + "actualCount": 188, "files": { "src/konpeito/Random.js": { "expectCount": 20, @@ -69,8 +69,8 @@ "undocumentLines": [] }, "src/senko/System.js": { - "expectCount": 33, - "actualCount": 33, + "expectCount": 34, + "actualCount": 34, "undocumentLines": [] }, "src/SenkoWSH.js": { diff --git a/docs/file/src/senko/SFile.js.html b/docs/file/src/senko/SFile.js.html index 7c6850b..451e093 100644 --- a/docs/file/src/senko/SFile.js.html +++ b/docs/file/src/senko/SFile.js.html @@ -180,32 +180,55 @@ /** * ファイルの移動 - * @param {string|SFile} file_obj + * - 移動後の `this` は、移動後のファイルを指す + * - `this` がファイルの場合、ディレクトリを選択すると、ディレクトリ内へファイルを移動させます + * - `this` がファイルの場合、ファイルを選択すると、ディレクトリの移動かつファイル名を変更します + * - `this` がディレクトリの場合、指定したディレクトリへファイルを移動させるため、ディレクトリ名の変更は行えません + * + * @param {string|SFile} file_obj - 移動先のファイル名及びディレクトリ * @returns {boolean} */ move(file_obj) { if(this.is_http) { throw "IllegalMethod"; } - const file = new SFile(file_obj); - if(this.isFile()) { - this.fso.MoveFile(this.pathname, file.getAbsolutePath()); - this.pathname = file.getAbsolutePath(); - return true; - } - else if(this.isDirectory()) { - this.fso.MoveFolder(this.pathname, file.getAbsolutePath()); - this.pathname = file.getAbsolutePath(); - return true; + const folder = new SFile(file_obj); + try { + if(this.isFile()) { + if(!folder.isDirectory()) { + // ディレクトリを指していない場合は、移動 + ファイル名の変更 + this.fso.MoveFile(this.pathname, folder.getAbsolutePath()); + this.pathname = folder.getAbsolutePath(); + } + else { + // 宛先がディレクトリ内へ移動になる + this.fso.MoveFile(this.pathname, folder.getAbsolutePath() + "\\"); + this.pathname = folder.getAbsolutePath() + "/" + this.getName(); + } + return true; + } + else if(this.isDirectory()) { + // フォルダを指定したフォルダ内へ移動 + this.fso.MoveFolder(this.getAbsolutePath(), folder.getAbsolutePath() + "/"); + this.pathname = folder.getAbsolutePath() + "/" + this.getName(); + return true; + } + else { + return false; + } } - else { + catch (e) { + console.log(e); return false; } } /** * ファイル名を変更 - * @param {string|SFile} file_obj + * - 変更後の `this` は、変更後のファイルを指す + * - 引数はフルパスを渡した場合でもファイル名のみ使用する + * + * @param {string|SFile} file_obj 変更後のファイル名 * @returns {boolean} */ renameTo(file_obj) { @@ -215,16 +238,27 @@ if(!this.isFile() && !this.isDirectory()) { return false; } - const file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname); - const name = new SFile(file_obj); - // 例えばファイル名を大文字から小文字に変換といった場合、 - // Scripting.FileSystemObject の仕様によりエラーが発生するため、 - // 別のファイル名を経由する - const key = ((Math.random() * 0x7FFFFFFF) & 0x7FFFFFFF).toString(16); - file.Name = name.getName() + key; - file.Name = name.getName(); - this.pathname = name.getAbsolutePath(); - return true; + // `GetFile` や `GetFolder` のプロパティ `.Name` で名前を変更した場合、 + // 例えばファイル名を大文字から小文字に変更すると + // `Scripting.FileSystemObject` の仕様によりエラーが発生する + // そのため `MoveFile`, `MoveFolder` を使用する + try { + // getAbsolutePath で取得すると同一名のファイルが正しく取得できないので + // 直接作成する + const dst = this.getParent() + "\\" + new SFile(file_obj).getName(); + if(this.isFile()) { + this.fso.MoveFile(this.getAbsolutePath(), dst); + } + else if(this.isDirectory()) { + this.fso.MoveFolder(this.getAbsolutePath(), dst); + } + this.pathname = new SFile(dst).getAbsolutePath(); + return true; + } + catch (e) { + console.log(e); + return false; + } } /** @@ -255,7 +289,9 @@ /** * 親フォルダの絶対パス - * URLなら最後にスラッシュをつけて返す + * - 通常のフォルダの場合は、最後の「`/`」は除去される + * - URLなら最後にスラッシュをつけて返す + * * @returns {string} */ getParent() { @@ -1329,39 +1365,75 @@ /** * 指定した条件にあうファイルを探す - * 関数を指定する場合は、ファイル名とフルパスが引数に渡されます - * @param {string|SFile|function(string, string): boolean} file_obj - * @returns {SFile|null} + * - 関数を指定する場合は、ファイル名とフルパスが引数に渡されます + * + * @param {string|SFile|RegExp|function(SFile): boolean} file_obj + * @param {boolean} [is_all_file=false] trueで指定した場合は条件に合うファイルを複数見つけて配列で返す + * @returns {SFile|SFile[]|null} */ - searchFile(file_obj) { - let target_file = null; + searchFile(file_obj, is_all_file) { + const is_all_file_ = is_all_file !== undefined ? is_all_file : false; + /** - * @type {function(string, string): boolean} + * @type {function(SFile): boolean} * @private */ let isTarget; if(typeof file_obj !== "function") { - const file = new SFile(file_obj); - const buffer = file.getName(); - isTarget = function(name, fullpath) { - return name === buffer; - }; + if(System.typeOf(file_obj) === "regexp") { + /** + * @type {RegExp} + */ + // @ts-ignore + const reg = file_obj; + isTarget = function(file) { + const result = reg.exec(file.getAbsolutePath()); + return result !== null; + }; + } + else { + // @ts-ignore + const file = new SFile(file_obj); + const buffer = file.getName(); + isTarget = function(file) { + return file.getName() === buffer; + }; + } } else { isTarget = file_obj; } + /** + * @type {SFile} + */ + let target_file = null; + /** + * @type {SFile[]} + */ + let target_files = []; /** * @type {function(SFile): boolean} */ const func = function(file) { - if(isTarget(file.getName(), file.getAbsolutePath())) { - target_file = file; - return false; + if(isTarget(file)) { + if(is_all_file_) { + target_files.push(file); + return true; + } + else { + target_file = file; + return false; + } } return true; }; this.each(func); - return target_file; + if(is_all_file_) { + return target_files; + } + else { + return target_file; + } } /** @@ -1523,7 +1595,6 @@ } extract_file = allfile[0]; } - const command = "\"" + tool_path + "\" x -y -o\"" + extract_dir + "\\\" \"" + extract_file + "\""; const result = System.exec("\"" + tool_path + "\" x -y -o\"" + extract_dir + "\\\" \"" + extract_file + "\""); if(result.exit_code !== 0) { if(temp_folder) { diff --git a/docs/file/src/senko/System.js.html b/docs/file/src/senko/System.js.html index 091116e..29dcdc1 100644 --- a/docs/file/src/senko/System.js.html +++ b/docs/file/src/senko/System.js.html @@ -662,6 +662,17 @@ return byte_array; } + /** + * データの型を小文字の英字で返す + * - 配列であれば `array`、正規表現であれば `regexp` などを返します + * + * @param {any} x + * @returns {string} + */ + static typeOf(x) { + return Object.prototype.toString.call(x).slice(8, -1).toLowerCase(); + } + } diff --git a/docs/index.json b/docs/index.json index d464c2a..058fe7b 100644 --- a/docs/index.json +++ b/docs/index.json @@ -6916,7 +6916,7 @@ "__docId__": 185, "kind": "file", "name": "src/senko/SFile.js", - "content": "/**\n * The script is part of SenkoWSH.\n * \n * AUTHOR:\n * natade (http://twitter.com/natadea)\n * \n * LICENSE:\n * The MIT license https://opensource.org/licenses/MIT\n */\n\nimport Polyfill from \"./polyfill/Polyfill.js\";\nimport Format from \"./Format.js\";\nimport System from \"./System.js\";\n \n/**\n * ファイル/フォルダ/URLを扱うクラス\n */\nexport default class SFile {\n\n\t/**\n\t * 初期化\n\t * @param {string|SFile} pathname ファイル名/フォルダ名/URLアドレス\n\t */\n\tconstructor(pathname) {\n\t\tif(arguments.length !== 1) {\n\t\t\tthrow \"IllegalArgumentException\";\n\t\t}\n\n\t\t/**\n\t\t * @type {string}\n\t\t * @private\n\t\t */\n\t\tthis.pathname = \"\";\n\n\t\tif((typeof pathname === \"string\")||(pathname instanceof String)) {\n\t\t\t// \\を/に置き換える\n\t\t\tthis.pathname = pathname.replace(/\\\\/g, \"/\" );\n\t\t}\n\t\t// (pathname instanceof SFile) が反応しない場合があるので以下を利用\n\t\telse if((pathname instanceof Object) && (\"getAbsolutePath\" in pathname)) {\n\t\t\tthis.pathname = pathname.getAbsolutePath();\n\t\t}\n\t\telse {\n\t\t\tthrow \"IllegalArgumentException\";\n\t\t}\n\t\t\n\t\t/**\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.is_http = /^htt/.test(this.pathname);\n\n\t\t/**\n\t\t * @type {any}\n\t\t * @private\n\t\t */\n\t\tthis.fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t}\n\n\t/**\n\t * ファイルの削除(ゴミ箱には入りません)\n\t * @param {boolean} [is_force=false] - 読み取り専用でも削除する\n\t * @returns {boolean}\n\t */\n\tremove(is_force) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\ttry {\n\t\t\tif(this.isFile()) {\n\t\t\t\treturn this.fso.DeleteFile(this.pathname, is_force ? is_force : false );\n\t\t\t}\n\t\t\telse if(this.isDirectory()) {\n\t\t\t\treturn this.fso.DeleteFolder(this.pathname, is_force ? is_force : false );\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイルが存在するか\n\t * @returns {boolean}\n\t */\n\texists() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tlet out = this.isFile();\n\t\tif(out === false) {\n\t\t\tout = this.isDirectory();\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * ファイルのコピー\n\t * @param {string|SFile} file_obj\n\t * @returns {boolean}\n\t */\n\tcopy(file_obj) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst file = new SFile(file_obj);\n\t\tif(this.isFile()) {\n\t\t\treturn this.fso.CopyFile(this.pathname, file.getAbsolutePath(), true);\n\t\t}\n\t\telse if(this.isDirectory()) {\n\t\t\treturn this.fso.CopyFolder(this.pathname, file.getAbsolutePath(), true);\n\t\t}\n\t\telse {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイルの移動\n\t * @param {string|SFile} file_obj\n\t * @returns {boolean}\n\t */\n\tmove(file_obj) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst file = new SFile(file_obj);\n\t\tif(this.isFile()) {\n\t\t\tthis.fso.MoveFile(this.pathname, file.getAbsolutePath());\n\t\t\tthis.pathname = file.getAbsolutePath();\n\t\t\treturn true;\n\t\t}\n\t\telse if(this.isDirectory()) {\n\t\t\tthis.fso.MoveFolder(this.pathname, file.getAbsolutePath());\n\t\t\tthis.pathname = file.getAbsolutePath();\n\t\t\treturn true;\n\t\t}\n\t\telse {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイル名を変更\n\t * @param {string|SFile} file_obj\n\t * @returns {boolean}\n\t */\n\trenameTo(file_obj) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\tconst name = new SFile(file_obj);\n\t\t// 例えばファイル名を大文字から小文字に変換といった場合、\n\t\t// Scripting.FileSystemObject の仕様によりエラーが発生するため、\n\t\t// 別のファイル名を経由する\n\t\tconst key = ((Math.random() * 0x7FFFFFFF) & 0x7FFFFFFF).toString(16);\n\t\tfile.Name = name.getName() + key;\n\t\tfile.Name = name.getName();\n\t\tthis.pathname = name.getAbsolutePath();\n\t\treturn true;\n\t}\n\n\t/**\n\t * 文字列化\n\t * @returns {string}\n\t */\n\ttoString() {\n\t\treturn this.getAbsolutePath();\n\t}\n\n\t/**\n\t * 名前を取得\n\t * @returns {string}\n\t */\n\tgetName() {\n\t\tif(this.is_http) {\n\t\t\t// 最後がスラッシュで終えている場合は、ファイル名取得できない\n\t\t\tif(this.isDirectory()) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tconst slashsplit = this.pathname.split(\"/\");\n\t\t\treturn slashsplit[slashsplit.length - 1];\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.GetFileName(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * 親フォルダの絶対パス\n\t * URLなら最後にスラッシュをつけて返す\n\t * @returns {string} \n\t */\n\tgetParent() {\n\t\tif(this.is_http) {\n\t\t\tlet path = this.getAbsolutePath();\n\t\t\t// 最後がスラッシュの場合でホスト名のみの場合は、これ以上辿れない。\n\t\t\tif(/^http[^/]+\\/\\/[^/]+\\/$/.test(path)) {\n\t\t\t\treturn path\n\t\t\t}\n\t\t\t// 最後がスラッシュの場合はスラッシュを除去\n\t\t\tif(/\\/$/.test(path)) {\n\t\t\t\tpath = path.substring(0 ,path.length - 1);\n\t\t\t}\n\t\t\t// フォルダ名までを削る\n\t\t\treturn path.match(/^.*\\//)[0];\n\t\t}\n\t\telse {\n\t\t\t// フォルダ名までのパスを取得する\n\t\t\tlet path = this.getAbsolutePath().match(/.*[/\\\\]/)[0];\n\t\t\t// フォルダを削る\n\t\t\tpath = path.substring(0 ,path.length - 1);\n\t\t\treturn path;\n\t\t}\n\t}\n\n\t/**\n\t * 親フォルダ\n\t * @returns {SFile}\n\t */\n\tgetParentFile() {\n\t\treturn new SFile(this.getParent());\n\t}\n\n\t/**\n\t * 拡張子(ドットを含まない)\n\t * @returns {string}\n\t */\n\tgetExtensionName() {\n\t\tif(this.is_http) {\n\t\t\tconst dotlist = this.getName().split(\".\");\n\t\t\treturn dotlist[dotlist.length - 1];\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.GetExtensionName(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * 絶対パスかどうか\n\t * @returns {boolean}\n\t */\n\tisAbsolute() {\n\t\tif(this.is_http) {\n\t\t\treturn this.getAbsolutePath() === this.pathname;\n\t\t}\n\t\telse {\n\t\t\tconst name = this.pathname.replace(\"/\", \"\\\\\");\n\t\t\treturn this.fso.GetAbsolutePathName(this.pathname) === name;\n\t\t}\n\t}\n\n\t/**\n\t * フォルダかどうか\n\t * @returns {boolean}\n\t */\n\tisDirectory() {\n\t\tif(this.is_http) {\n\t\t\t// 最後がスラッシュで終えている場合はディレクトリ\n\t\t\treturn /\\/$/.test(this.pathname);\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.FolderExists(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * ファイルかどうか\n\t * @returns {boolean}\n\t */\n\tisFile() {\n\t\tif(this.is_http) {\n\t\t\t// 最後がスラッシュで終えていない場合はファイル\n\t\t\treturn /[^/]$/.test(this.pathname);\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.FileExists(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * 読み取り専用ファイルかどうか\n\t * @returns {boolean}\n\t */\n\tisReadOnly() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst ATTRIBUTES_READONLY = 1;\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\treturn (file.Attributes & ATTRIBUTES_READONLY) !== 0;\n\t}\n\t\n\t/**\n\t * 読み取り専用ファイルかどうかを設定する\n\t * @param {boolean} is_readonly\n\t * @param {boolean} [is_allfiles=false]\n\t * @returns {boolean}\n\t */\n\tsetReadOnly(is_readonly, is_allfiles) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst ATTRIBUTES_READONLY = 1;\n\t\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\t\tif(is_readonly) {\n\t\t\t\tfile.Attributes = file.Attributes | ATTRIBUTES_READONLY;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfile.Attributes = file.Attributes & ~ATTRIBUTES_READONLY;\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t\tif(this.isFile() || !is_allfiles) {\n\t\t\treturn true;\n\t\t}\n\t\tlet ret = true;\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tret = ret && file.setReadOnly(is_readonly, false);\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn ret;\n\t}\n\n\t/**\n\t * 隠しファイルかどうか\n\t * @returns {boolean}\n\t */\n\tisHidden() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst ATTRIBUTES_HIDDEN = 2;\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\treturn (file.Attributes & ATTRIBUTES_HIDDEN) !== 0;\n\t}\n\t\n\t/**\n\t *隠しファイルかどうかを設定する\n\t * @param {boolean} is_hidden\n\t * @param {boolean} [is_allfiles=false]\n\t * @returns {boolean}\n\t */\n\tsetHidden(is_hidden, is_allfiles) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst ATTRIBUTES_HIDDEN = 2;\n\t\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\t\tif(is_hidden) {\n\t\t\t\tfile.Attributes = file.Attributes | ATTRIBUTES_HIDDEN;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfile.Attributes = file.Attributes & ~ATTRIBUTES_HIDDEN;\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t\tif(this.isFile() || !is_allfiles) {\n\t\t\treturn true;\n\t\t}\n\t\tlet ret = true;\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tret = ret && file.setHidden(is_hidden, false);\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn ret;\n\t}\n\n\t/**\n\t * 更新日を取得\n\t * @returns {Date}\n\t */\n\tlastModified() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn null;\n\t\t}\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\t// DateLastModified は VT_DATE 値なので変換する\n\t\treturn new Date(file.DateLastModified);\n\t}\n\n\t/**\n\t * 更新日を設定(ファイルのみ対応)\n\t * @param {Date} date\n\t * @returns {boolean}\n\t */\n\tsetLastModified(date) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile()) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst shell = new ActiveXObject(\"Shell.Application\");\n\t\t\tconst folder = shell.NameSpace(this.getParent());\n\t\t\tconst file = folder.ParseName(this.getName());\n\t\t\tconst date_string = Format.datef(\"YYYY/MM/DD hh:mm:ss\", date);\n\t\t\tfile.ModifyDate = date_string;\n\t\t\treturn true;\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイルサイズ\n\t * @returns {number}\n\t */\n\tlength() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn -1;\n\t\t}\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\treturn file.Size;\n\t}\n\n\t/**\n\t * 配下のファイル名の一覧を取得\n\t * @returns {string[]}\n\t */\n\tgetFiles() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn null;\n\t\t}\n\t\tconst out = [];\n\t\tconst list = new Enumerator(this.fso.GetFolder(this.pathname).Files);\n\t\tfor(let i = 0; !list.atEnd(); list.moveNext()) {\n\t\t\tout[i++] = list.item().Name;\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 配下のサブフォルダ名の一覧を取得\n\t * @returns {string[]}\n\t */\n\tgetSubFolders() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn null;\n\t\t}\n\t\tconst out = [];\n\t\tconst list = new Enumerator(this.fso.GetFolder(this.pathname).SubFolders);\n\t\tfor(let i = 0; !list.atEnd(); list.moveNext()) {\n\t\t\tout[i++] = list.item().Name;\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 区切り文字と終端を正規化した文字列を取得\n\t * @returns {string}\n\t */\n\tgetNormalizedPathName() {\n\t\tif(this.pathname === \"\") {\n\t\t\treturn \".\\\\\";\n\t\t}\n\t\tlet name = this.pathname.replace(/\\//g, \"\\\\\");\n\t\tif(name.slice(-1) !== \"\\\\\") {\n\t\t\tname += \"\\\\\";\n\t\t}\n\t\treturn name;\n\t}\n\n\t/**\n\t * 配下のファイル名とフォルダ名を取得\n\t * @returns {string[]}\n\t */\n\tlist() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn null;\n\t\t}\n\t\tconst files = this.getFiles();\n\t\tconst subfolders = this.getSubFolders();\n\t\tconst out = [];\n\t\tfor(let j = 0; j < subfolders.length;) {\n\t\t\tout.push(subfolders[j++]);\n\t\t}\n\t\tfor(let j = 0; j < files.length;) {\n\t\t\tout.push(files[j++]);\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 絶対パスを取得\n\t * @returns {string}\n\t */\n\tgetAbsolutePath() {\n\t\tif(this.is_http) {\n\t\t\t// ホストとファイルに分ける\n\t\t\tconst hosttext = this.pathname.match(/^http[^/]+\\/\\/[^/]+\\//)[0];\n\t\t\tconst filetext = this.pathname.substr(hosttext.length);\n\t\t\t// パスを1つずつ解析しながら辿っていく\n\t\t\tlet name = hosttext;\n\t\t\tconst namelist = filetext.split(\"/\");\n\t\t\tlet i;\n\t\t\tfor(i = 0; i < namelist.length; i++) {\n\t\t\t\tif((namelist[i] === \"\") || (namelist[i] === \".\")) {\n\t\t\t\t\t// 階層は移動しない\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(namelist[i] === \"..\") {\n\t\t\t\t\t// 上の階層へ移動する\n\t\t\t\t\tname = name.substring(0 ,name.length - 1).match(/.*\\//)[0];\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// フォルダ名 + \"/\"\n\t\t\t\tname += namelist[i];\n\t\t\t\tif(i !== namelist.length - 1) {\n\t\t\t\t\tname += \"/\";\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn name;\n\t\t}\n\t\telse {\n\t\t\t// `*:` という2文字のパスで `C` 以外を設定した場合に正しいパスを設定できない不具合がある\n\t\t\t// 従って、防止用に、最後にコロンが付いている場合は\"C:\"とかなので\"C:/\"としてからパスを変換する\n\t\t\tif(/:$/.test(this.pathname)) {\n\t\t\t\treturn this.fso.GetAbsolutePathName(this.pathname + \"\\\\\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn this.fso.GetAbsolutePathName(this.pathname);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * フォルダを作成\n\t * - フォルダは1つのみ指定可能\n\t * - すでにフォルダがある場合はエラーを返す。\n\t * @returns {boolean}\n\t */\n\tmkdir() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst filename = this.getAbsolutePath();\n\t\tif(this.fso.FileExists(filename)) {\n\t\t\t// ファイルがあるため、フォルダを作れない\n\t\t\treturn false;\n\t\t}\n\t\telse if(this.fso.FolderExists(filename)) {\n\t\t\t// フォルダが既にあるため、TRUEで返す\n\t\t\treturn true;\n\t\t}\n\t\t// フォルダがないので作成する\n\t\tthis.fso.CreateFolder(filename);\n\t\t// 10秒間作られるまで待つ\n\t\tfor(let i = 0; i < (20 * 10); i++) {\n\t\t\tif(this.fso.FolderExists(filename)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tWScript.Sleep(50); // 50ms\n\t\t}\n\t\t// いつまで待ってもフォルダが作られないので失敗\n\t\treturn false;\n\t}\n\n\t/**\n\t * フォルダを作成\n\t * - 作成したいフォルダを続けて記載が可能\n\t * - フォルダがない場合はフォルダを作成していく\n\t * @returns {boolean}\n\t */\n\tmkdirs() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst name = this.pathname.replace(/\\//g, \"\\\\\").split(\"\\\\\");\n\t\tlet dir = \"\";\n\t\tfor(let i = 0; i < name.length; i++) {\n\t\t\tdir += name[i];\n\t\t\tif(!(new SFile(dir)).mkdir()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdir += \"\\\\\";\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 実行ファイルを起動する\n\t * @param {number} [style=1] - 起動オプション\n\t * @param {boolean} [is_wait=false] - プロセスが終了するまで待つ\n\t * @returns {void}\n\t */\n\trun(style, is_wait) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst NormalFocus = 1;\n\t\tconst intWindowStyle = style !== undefined ? style : NormalFocus;\n\t\tconst bWaitOnReturn = is_wait !== undefined ? is_wait : false;\n\t\tconst objWShell = new ActiveXObject(\"WScript.Shell\");\n\t\t// @ts-ignore\n\t\tobjWShell.Run(this.getAbsolutePath(), intWindowStyle, bWaitOnReturn);\n\t}\n\n\t/**\n\t * 1行書き加える\n\t * @param {string} text\n\t * @returns {boolean}\n\t */\n\twriteLine(text) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tlet file;\n\t\tif(this.isFile()) {\n\t\t\tconst ForAppending = 8;\n\t\t\tfile = this.fso.OpenTextFile(this.pathname, ForAppending);\n\t\t}\n\t\telse if(this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\telse {\n\t\t\tfile = this.fso.CreateTextFile(this.pathname, true);\n\t\t}\n\t\tfile.WriteLine(text);\n\t\tfile.Close();\n\t\treturn true;\n\t}\n\n\t/**\n\t * ローカル、インターネット上のファイルをテキストとして開く\n\t * - 改行コードは `\\n` に統一されます\n\t * \n\t * @param {string} [charset=\"_autodetect_all\"] - 文字コード\n\t * @returns {string} 失敗時は null\n\t */\n\tgetTextFile(charset) {\n\t\tconst icharset = charset !== undefined ? charset : \"_autodetect_all\";\n\t\tconst inewline = \"\\n\"; //javascript上での改行\n\t\tlet text = null;\n\t\tif(/^htt/.test(this.pathname)) {\n\t\t\tconst http = System.createXMLHttpRequest();\n\t\t\tif(http === null) {\n\t\t\t\tconsole.log(\"createXMLHttpRequest\")\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thttp.open(\"GET\", this.pathname, false);\n\t\t\ttry {\n\t\t\t\thttp.send(null);\n\t\t\t\tif(http.status === 200) {\n\t\t\t\t\ttext = http.responseText;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.log(\"HTTP status codes \" + http.status);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst is_fso = /shift_jis|sjis|ascii|unicode|utf-16le/i.test(icharset);\n\t\t\tif(is_fso) {\n\t\t\t\t// Scripting.FileSystemObject で開く\n\t\t\t\t// 入出力モード = 読取専用モード\n\t\t\t\tconst ForReading = 1;\n\t\t\t\tconst mode = ForReading;\n\t\t\t\t// ファイルの新規作成 = 新規作成しない\n\t\t\t\tconst option = false;\n\t\t\t\t// 文字のエンコード\n\t\t\t\tconst TristateFalse\t\t\t= 0;\t// ASCII(Shift-JIS)\n\t\t\t\tconst TristateTrue\t\t\t= -1;\t// Unicode(UTF-16)\n\t\t\t\tconst TristateUseDefault\t= -2;\t// システムの規定値\n\t\t\t\tlet tristate = 0;\n\t\t\t\tif(/ascii/i.test(icharset)) {\n\t\t\t\t\t// ASCII\n\t\t\t\t\ttristate = TristateFalse;\n\t\t\t\t}\n\t\t\t\telse if(/shift_jis|sjis/i.test(icharset)) {\n\t\t\t\t\t// システムのデフォルト(日本語のOSだと仮定)\n\t\t\t\t\ttristate = TristateUseDefault;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// utf-16le\n\t\t\t\t\ttristate = TristateTrue;\n\t\t\t\t}\n\t\t\t\tconst open_file = this.fso.OpenTextFile(this.pathname, mode, option, tristate );\n\t\t\t\ttext = open_file.ReadAll();\n\t\t\t\topen_file.Close();\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// 自由な文字エンコードで開く(速度は遅い)\n\t\t\t\t// 使用可能な charset については下記を参照\n\t\t\t\t// HKEY_CLASSES_ROOT\\MIME\\Database\\Charset\n\t\t\t\tconst adTypeText = 2;\n\t\t\t\tconst adReadAll = -1;\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = icharset;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\ttext = stream.readText(adReadAll);\n\t\t\t\tstream.close();\n\t\t\t\t// 文字コードが自動取得の場合、BOMまで読み込んでしまうのを防止する\n\t\t\t\tif((icharset === \"_autodetect_all\")||(icharset === \"_autodetect\")) {\n\t\t\t\t\tlet newcharset = \"\";\n\t\t\t\t\t// 1文字以上のとき\n\t\t\t\t\tif(text.length > 1) {\n\t\t\t\t\t\t// utf-16le\n\t\t\t\t\t\tif(text.charCodeAt(0) === 0xfeff) {\n\t\t\t\t\t\t\t// 通常は、このルートはBOM付きutf-16leのときに通るが、\n\t\t\t\t\t\t\t// BOM付きutf-8でも通る場合がなぜかある。(後述)\n\t\t\t\t\t\t\tnewcharset = \"unicode\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// utf-16be\n\t\t\t\t\t\telse if(text.charCodeAt(0) === 0xfffe) {\n\t\t\t\t\t\t\tnewcharset = \"unicodeFFFE\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 2文字以上のとき\n\t\t\t\t\tif(text.length > 2) {\n\t\t\t\t\t\t// BOM付きutf-8でなぜかこの文字がくっつく場合がある。\n\t\t\t\t\t\tif(\t(text.charCodeAt(0) === 0x30fb) &&\n\t\t\t\t\t\t\t(text.charCodeAt(1) === 0xff7f)) {\n\t\t\t\t\t\t\tnewcharset = \"utf-8\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 3文字以上のとき\n\t\t\t\t\tif(text.length > 3) {\n\t\t\t\t\t\t// utf-8\n\t\t\t\t\t\tif(\t(text.charCodeAt(0) === 0xef) &&\n\t\t\t\t\t\t\t(text.charCodeAt(1) === 0xbb) &&\n\t\t\t\t\t\t\t(text.charCodeAt(2) === 0xbf)) {\n\t\t\t\t\t\t\tnewcharset = \"utf-8\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 上判定でBOM付きが分かった場合、正しい文字コードで取得する\n\t\t\t\t\tif(newcharset !== \"\") {\n\t\t\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\t\t\tstream.type = adTypeText;\n\t\t\t\t\t\tstream.charset = newcharset;\n\t\t\t\t\t\tstream.open();\n\t\t\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\t\t\ttext = stream.readText(adReadAll);\n\t\t\t\t\t\tstream.close();\n\t\t\t\t\t}\n\t\t\t\t\t// BOM付きutf-8 でも BOM付きutf-16le と判定した場合の対処\n\t\t\t\t\tif((text.length > 1) && (text.charCodeAt(0) === 0xbbef)) {\n\t\t\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\t\t\tstream.type = adTypeText;\n\t\t\t\t\t\tstream.charset = \"utf-8\";\n\t\t\t\t\t\tstream.open();\n\t\t\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\t\t\ttext = stream.readText(adReadAll);\n\t\t\t\t\t\tstream.close();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(text !== null) {\n\t\t\treturn text.replace(/\\r\\n?|\\n/g, inewline); //改行コードを統一\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * テキストファイルを保存\n\t * @param {string} text\n\t * @param {string} [charset=\"utf-8\"] - 文字コード\n\t * @param {string} [newline=\"\\n\"] - 改行コード\n\t * @param {boolean} [issetBOM=true] - BOMの有無(`utf-8`のみ有効 )\n\t * @returns {boolean}\n\t */\n\tsetTextFile(text, charset, newline, issetBOM) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst icharset = charset !== undefined ? charset : \"utf-8\";\n\t\tconst inewline = newline !== undefined ? newline : \"\\n\";\n\t\tconst iissetBOM = issetBOM !== undefined ? issetBOM : true; //utf-8のみ有効 BOMありかなし\n\t\tconst is_fso = /shift_jis|sjis|ascii|unicode|utf-16le/i.test(icharset);\n\t\tif(is_fso) {\n\t\t\t// Scripting.FileSystemObject で書き込む\n\t\t\t// 入出力モード = 上書きモード\n\t\t\tconst ForWriting = 2;\n\t\t\tconst mode = ForWriting;\n\t\t\t// ファイルの新規作成 = 作成\n\t\t\tconst option = true;\n\t\t\t// 文字のエンコード\n\t\t\tconst TristateFalse\t\t\t= 0;\t// ASCII(Shift-JIS)\n\t\t\tconst TristateTrue\t\t\t= -1;\t// Unicode(UTF-16)\n\t\t\tconst TristateUseDefault\t= -2;\t// システムの規定値\n\t\t\tlet tristate = 0;\n\t\t\tif(/ascii/i.test(icharset)) {\n\t\t\t\t// ASCII\n\t\t\t\ttristate = TristateFalse;\n\t\t\t}\n\t\t\telse if(/shift_jis|sjis/i.test(icharset)) {\n\t\t\t\t// システムのデフォルト(日本語のOSだと仮定)\n\t\t\t\ttristate = TristateUseDefault;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// utf-16le\n\t\t\t\ttristate = TristateTrue;\n\t\t\t}\n\t\t\tconst open_file = this.fso.OpenTextFile(this.pathname, mode, option, tristate );\n\t\t\topen_file.Write(text.replace(/\\r\\n?|\\n/g, inewline));\n\t\t\topen_file.Close();\n\t\t}\n\t\telse {\n\t\t\t// ADODB.Streamで書き込む\n\t\t\tconst adTypeBinary = 1;\n\t\t\tconst adTypeText = 2;\n\t\t\tconst adSaveCreateOverWrite = 2;\n\t\t\ttry {\n\t\t\t\t// 使用可能な charset については下記を参照\n\t\t\t\t// HKEY_CLASSES_ROOT\\MIME\\Database\\Charset\n\t\t\t\tlet stream;\n\t\t\t\tstream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = icharset;\n\t\t\t\tstream.open();\n\t\t\t\tstream.writeText(text.replace(/\\r\\n?|\\n/g, inewline)); //改行コードを統一\n\t\t\t\tif(/utf-8/.test(icharset.toLowerCase()) && (!iissetBOM)) {\n\t\t\t\t\t// バイナリ型にして3バイト目以降をバイト型で取得\n\t\t\t\t\tstream.position = 0;\n\t\t\t\t\tstream.type = adTypeBinary;\n\t\t\t\t\tstream.position = 3;\n\t\t\t\t\tconst binary = stream.read();\n\t\t\t\t\tstream.close();\n\t\t\t\t\t// 取得したバイナリデータを1バイト目から書きこむ\n\t\t\t\t\tstream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\t\tstream.type = adTypeBinary;\n\t\t\t\t\tstream.open();\n\t\t\t\t\tstream.write(binary);\n\t\t\t\t}\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * ローカル、インターネット上のファイルをバイナリとして開く\n\t * - 参考速度:0.5 sec/MB\n\t * - 巨大なファイルの一部を調べる場合は、位置とサイズを指定した方がよい\n\t * \n\t * @param {number} [offset] - 位置(※ 指定すると速度が低下する)\n\t * @param {number} [size] - サイズ(※ 指定すると速度が低下する)\n\t * @returns {number[]}\n\t */\n\tgetBinaryFile(offset, size) {\n\t\tif(/^htt/.test(this.pathname)) {\n\t\t\tconst http = System.createXMLHttpRequest();\n\t\t\tif(http === null) {\n\t\t\t\tconsole.log(\"createXMLHttpRequest\")\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thttp.open(\"GET\", this.pathname, false);\n\t\t\tlet byte_array = null;\n\t\t\ttry {\n\t\t\t\thttp.send(null);\n\t\t\t\tif(http.status === 200) {\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tbyte_array = http.responseBody;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.log(\"HTTP status codes \" + http.status);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn System.createNumberArrayFromByteArray(byte_array);\n\t\t}\n\t\t// 位置を無指定\n\t\tif(offset === undefined) {\n\t\t\tconst adTypeText = 2;\n\t\t\tconst adReadAll = -1;\n\t\t\tconst charset = \"iso-8859-1\";\n\t\t\t/**\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t\t\tconst map = {\n\t\t\t\t0x20AC\t:\t0x80\t,\t//\t8364\t128\n\t\t\t\t0x201A\t:\t0x82\t,\t//\t8218\t130\n\t\t\t\t0x0192\t:\t0x83\t,\t//\t402\t131\n\t\t\t\t0x201E\t:\t0x84\t,\t//\t8222\t132\n\t\t\t\t0x2026\t:\t0x85\t,\t//\t8230\t133\n\t\t\t\t0x2020\t:\t0x86\t,\t//\t8224\t134\n\t\t\t\t0x2021\t:\t0x87\t,\t//\t8225\t135\n\t\t\t\t0x02C6\t:\t0x88\t,\t//\t710\t136\n\t\t\t\t0x2030\t:\t0x89\t,\t//\t8240\t137\n\t\t\t\t0x0160\t:\t0x8A\t,\t//\t352\t138\n\t\t\t\t0x2039\t:\t0x8B\t,\t//\t8249\t139\n\t\t\t\t0x0152\t:\t0x8C\t,\t//\t338\t140\n\t\t\t\t0x017D\t:\t0x8E\t,\t//\t381\t142\n\t\t\t\t0x2018\t:\t0x91\t,\t//\t8216\t145\n\t\t\t\t0x2019\t:\t0x92\t,\t//\t8217\t146\n\t\t\t\t0x201C\t:\t0x93\t,\t//\t8220\t147\n\t\t\t\t0x201D\t:\t0x94\t,\t//\t8221\t148\n\t\t\t\t0x2022\t:\t0x95\t,\t//\t8226\t149\n\t\t\t\t0x2013\t:\t0x96\t,\t//\t8211\t150\n\t\t\t\t0x2014\t:\t0x97\t,\t//\t8212\t151\n\t\t\t\t0x02DC\t:\t0x98\t,\t//\t732\t152\n\t\t\t\t0x2122\t:\t0x99\t,\t//\t8482\t153\n\t\t\t\t0x0161\t:\t0x9A\t,\t//\t353\t154\n\t\t\t\t0x203A\t:\t0x9B\t,\t//\t8250\t155\n\t\t\t\t0x0153\t:\t0x9C\t,\t//\t339\t156\n\t\t\t\t0x017E\t:\t0x9E\t,\t//\t382\t158\n\t\t\t\t0x0178\t:\t0x9F\t\t//\t376\t159\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = charset;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\tconst text = stream.readText(adReadAll);\n\t\t\t\tstream.close();\n\t\t\t\tconst out = new Array(text.length);\n\t\t\t\tfor(let i = 0;i < text.length;i++) {\n\t\t\t\t\tconst x = text.charCodeAt(i);\n\t\t\t\t\tif(0xFF < x) {\n\t\t\t\t\t\tout[i] = map[x];\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tout[i] = x;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\ttry {\n\t\t\t\tconst filesize = this.length();\n\t\t\t\tif(filesize === -1) {\n\t\t\t\t\tconsole.log(\"filesize error\");\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\t// 位置を指定している場合\n\t\t\t\tif(offset < 0 || filesize <= offset) {\n\t\t\t\t\tconsole.log(\"offset error\");\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tconst ioffset = offset;\n\t\t\t\tlet isize = size !== undefined ? size : filesize - ioffset;\n\t\t\t\t// 長さのチェック\n\t\t\t\tif(filesize < (ioffset + isize) || isize < 0) {\n\t\t\t\t\tisize = filesize - ioffset;\n\t\t\t\t}\n\t\t\t\t// バイト配列を読み込む\n\t\t\t\tconst adTypeBinary = 1;\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.Type = adTypeBinary;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\tstream.position = ioffset;\n\t\t\t\tconst byte_array = stream.read(isize);\n\t\t\t\tstream.close();\n\t\t\t\treturn System.createNumberArrayFromByteArray(byte_array);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * バイナリファイルを保存\n\t * - 参考速度:1.0 sec/MB\n\t * \n\t * @param {number[]} array_\n\t * @param {number} [offset] - 位置(※ 指定すると速度が低下する)\n\t * @returns {boolean}\n\t */\n\tsetBinaryFile(array_, offset) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\t// 位置を無指定\n\t\tlet is_write = true;\n\t\tif((offset === undefined) || offset === 0) {\n\t\t\ttry {\n\t\t\t\tconst adTypeText = 2;\n\t\t\t\tconst adSaveCreateOverWrite = 2;\n\t\t\t\tconst charset = \"iso-8859-1\";\n\t\t\t\tconst buffersize = 1024 * 128;\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = charset;\n\t\t\t\tstream.open();\n\t\t\t\tfor(let i = 0;i < array_.length;) {\n\t\t\t\t\tconst text = [];\n\t\t\t\t\tfor(let j = 0; (j < buffersize) && (i < array_.length); j++, i++) {\n\t\t\t\t\t\ttext[j] = String.fromCharCode(array_[i]);\n\t\t\t\t\t}\n\t\t\t\t\tstream.writeText(text.join(\"\"));\n\t\t\t\t}\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\tis_write = false;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst adTypeBinary = 1;\n\t\t\tconst adSaveCreateOverWrite = 2;\n\t\t\tif(!this.isFile()) {\n\t\t\t\tconst byte_array = System.createByteArrayFromNumberArray(array_, offset);\n\t\t\t\tif(byte_array === null) {\n\t\t\t\t\tconsole.log(\"createByteArrayFromNumberArray\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.Type = adTypeBinary;\n\t\t\t\tstream.open();\n\t\t\t\tstream.write(byte_array);\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst byte_array = System.createByteArrayFromNumberArray(array_);\n\t\t\t\tif(byte_array === null) {\n\t\t\t\t\tconsole.log(\"createByteArrayFromNumberArray\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.Type = adTypeBinary;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\tstream.position = offset;\n\t\t\t\tstream.write(byte_array);\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\tis_write = false;\n\t\t\t}\n\t\t}\n\t\treturn is_write;\n\t}\n\n\t/**\n\t * ファイルのハッシュ値を計算する\n\t * @param {string} [algorithm=\"MD5\"] - アルゴリズム\n\t * @returns {string} 半角英数の16進数で表したハッシュ値、失敗時は`\"0\"`\n\t */\n\tgetHashCode(algorithm) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile()) {\n\t\t\treturn \"0\";\n\t\t}\n\t\tconst algorithm_ = algorithm !== undefined ? algorithm : \"MD5\";\n\t\tconst message = \"certutil -hashfile \\\"\" + this.getAbsolutePath() + \"\\\" \" + algorithm_.toUpperCase();\n\t\tconst output = System.exec(message);\n\t\tif(output.exit_code !== 0) {\n\t\t\treturn \"0\";\n\t\t}\n\t\t// 2行目を抽出する\n\t\tconst hash_lines = output.out.split(/\\n/);\n\t\tif(hash_lines.length <= 1) {\n\t\t\treturn \"0\";\n\t\t}\n\t\t// 2種類のタイプを検知させる\n\t\t// - dcd802e3848075716e92424cfdcb9c0d (Windows 10)\n\t\t// - dc d8 02 e3 84 80 75 71 6e 92 42 4c fd cb 9c 0d (Windows8.1)\n\t\tconst hash = hash_lines[1].trim().toLowerCase().match(/^(([0-9a-f]{2}){8,})|((([0-9a-f]{2} ){7,})[0-9a-f]{2})$/);\n\t\tif(hash === null) {\n\t\t\treturn \"0\";\n\t\t}\n\t\treturn hash[0].replace(/ /g, \"\");\n\t}\n\n\t/**\n\t * テンポラリフォルダ内の適当なファイル名を取得\n\t * @returns {SFile}\n\t */\n\tstatic createTempFile() {\n\t\tconst TemporaryFolder = 2;\n\t\tconst fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t\t// テンポラリフォルダ内の適当なファイル名を取得します\n\t\treturn new SFile(fso.GetSpecialFolder(TemporaryFolder) + \"\\\\\" + fso.GetTempName());\n\t}\n\n\t/**\n\t * カレントディレクトリを取得\n\t * @returns {SFile}\n\t */\n\tstatic getCurrentDirectory() {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\treturn new SFile(shell.CurrentDirectory);\n\t}\n\n\t/**\n\t * カレントディレクトリを設定\n\t * @param {string|SFile} file_obj\n\t */\n\tstatic setCurrentDirectory(file_obj) {\n\t\tconst file = new SFile(file_obj);\n\t\tconst shell = WScript.CreateObject (\"WScript.Shell\");\n\t\tconst fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t\tshell.CurrentDirectory = fso.GetFolder(file.getAbsolutePath()).Name;\n\t}\n\n\t/**\n\t * フォルダの中のフォルダとファイルに対して指定した関数を実行する\n\t * @param {function(SFile): boolean} func 戻り値が`false`で処理を終了。\n\t * @returns {boolean} result\n\t */\n\teach(func) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn func.call(func, this);\n\t\t}\n\t\tconst path = [];\n\t\tconst collection = [];\n\t\tlet file;\n\t\tlet pointer = 0;\n\t\tlet list;\n\t\tlet targetfolder;\n\t\tpath[pointer] = this.getNormalizedPathName();\n\n\t\t// 1階層目を処理する\n\t\ttargetfolder = this.fso.GetFolder(path[pointer]);\n\t\tlist = new Enumerator(this.fso.GetFolder(targetfolder).Files);\n\t\tfor(; !list.atEnd(); list.moveNext()) {\n\t\t\tfile = new SFile(path[pointer] + list.item().Name);\n\t\t\tif(!func.call(func, file)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// 2階層目以降を処理する\n\t\tif(targetfolder.SubFolders.Count === 0) {\n\t\t\treturn false;\n\t\t}\n\t\tcollection[pointer] = new Enumerator(targetfolder.SubFolders);\n\t\tpointer++;\n\t\twhile(true) {\n\t\t\tpath[pointer] = path[pointer - 1] + collection[pointer - 1].item().Name;\n\t\t\tfile = new SFile(path[pointer]);\n\t\t\tif(!func.call(func, file)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tpath[pointer] += \"\\\\\";\n\t\t\ttargetfolder = this.fso.GetFolder(path[pointer]);\n\t\t\tlist = new Enumerator(targetfolder.Files);\n\t\t\tfor(; !list.atEnd(); list.moveNext()) {\n\t\t\t\tfile = new SFile(path[pointer] + list.item().Name);\n\t\t\t\tif(!func.call(func, file)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(targetfolder.SubFolders.Count === 0) {\n\t\t\t\twhile(true) {\n\t\t\t\t\tif(pointer === 0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcollection[pointer - 1].moveNext();\n\t\t\t\t\tif(collection[pointer - 1].atEnd()) {\n\t\t\t\t\t\tpointer--;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(pointer === 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcollection[pointer] = new Enumerator(targetfolder.SubFolders);\n\t\t\t\tpointer++;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * サブフォルダの中まで探索して全てのファイルとフォルダを取得\n\t * @returns {SFile[]}\n\t */\n\tgetAllFiles() {\n\t\t/**\n\t\t * @type {SFile[]}\n\t\t */\n\t\tconst out = [];\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tout.push(file);\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn out;\n\t}\n\n\t/**\n\t * 指定した条件にあうファイルを探す\n\t * 関数を指定する場合は、ファイル名とフルパスが引数に渡されます\n\t * @param {string|SFile|function(string, string): boolean} file_obj\n\t * @returns {SFile|null}\n\t */\n\tsearchFile(file_obj) {\n\t\tlet target_file = null;\n\t\t/**\n\t\t * @type {function(string, string): boolean}\n\t\t * @private\n\t\t */\n\t\tlet isTarget;\n\t\tif(typeof file_obj !== \"function\") {\n\t\t\tconst file = new SFile(file_obj);\n\t\t\tconst buffer = file.getName();\n\t\t\tisTarget = function(name, fullpath) {\n\t\t\t\treturn name === buffer;\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\tisTarget = file_obj;\n\t\t}\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tif(isTarget(file.getName(), file.getAbsolutePath())) {\n\t\t\t\ttarget_file = file;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn target_file;\n\t}\n\n\t/**\n\t * 圧縮する\n\t * - 圧縮後のファイル名の拡張子で圧縮したい形式を指定する\n\t * - Windows標準の機能を使用して圧縮する( `zip` のみ対応)\n\t * - 外部ツール `7-Zip` がインストール/設定されている場合は、それを利用して圧縮する\n\t * \n\t * @param {SFile|string|SFile[]|string[]} input_file 圧縮したいファイル\n\t * @param {SFile|string} output_file 圧縮後のファイル名\n\t * @returns {boolean} result\n\t */\n\tstatic compress(input_file, output_file) {\n\t\tconst compress_file = new SFile(output_file);\n\t\t// ファイルの拡張子を調べる\n\t\tlet comp_type = null;\n\t\tif(compress_file.getName().toLowerCase().endsWith(\".tar.gz\")) {\n\t\t\tcomp_type = \"targz\"\n\t\t}\n\t\telse {\n\t\t\tcomp_type = compress_file.getExtensionName().toLowerCase();\n\t\t}\n\t\t// 利用するツールを選択する\n\t\tconst tool_path = SFile.getCompressTool();\n\t\t// 圧縮したい対象のファイル一覧を作成\n\t\tconst file_list_buf = Array.isArray(input_file) ? input_file : [input_file];\n\t\t/**\n\t\t * @type {SFile[]}\n\t\t */\n\t\tlet file_list = [];\n\t\t// ファイルチェック\n\t\tfor(let i = 0;i < file_list_buf.length; i++) {\n\t\t\tfile_list[i] = new SFile(file_list_buf[i]);\n\t\t\tif(!(file_list[i].exists())) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t// 入力ファイル数が1つで拡張子がtarの場合\n\t\tif(file_list.length === 1 && file_list[0].getExtensionName().toLowerCase() === \"tar\") {\n\t\t\tcomp_type = compress_file.getExtensionName().toLowerCase();\n\t\t}\n\t\tif(tool_path === null) {\n\t\t\tif(comp_type === \"zip\") {\n\t\t\t\tconst shell = new ActiveXObject(\"Shell.Application\");\n\t\t\t\tconst fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t\t\t\t// ZIPファイルを作成\n\t\t\t\tcompress_file.setBinaryFile([0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);\n\t\t\t\tconst zip = shell.NameSpace(compress_file.getAbsolutePath());\n\t\t\t\t// 1つずつデータを入れていく\n\t\t\t\tfor(let i = 0; i < file_list.length; i++) {\n\t\t\t\t\tconst name = file_list[i].getAbsolutePath();\n\t\t\t\t\tzip.CopyHere(name, 4);\n\t\t\t\t\t// コピーが終わるまで wait\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tSystem.sleep(0.1);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst ForAppending = 8;\n\t\t\t\t\t\t\tfso.OpenTextFile(compress_file.getAbsolutePath(), ForAppending).Close();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tlet temp_folder = null;\n\t\t\t// targzの場合はtarだけ作成する\n\t\t\tif(comp_type === \"targz\") {\n\t\t\t\ttemp_folder = SFile.createTempFile();\n\t\t\t\ttemp_folder.mkdirs();\n\t\t\t\tconst name = compress_file.getName();\n\t\t\t\tconst tar_file = temp_folder + \"\\\\\" + name.substr(0, name.length - \".tar.gz\".length ) + \".tar\";\n\t\t\t\tfor(let i = 0; i < file_list.length; i++) {\n\t\t\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" a \\\"\" + tar_file + \"\\\" \\\"\" + file_list[i] + \"\\\"\");\n\t\t\t\t\tif(result.exit_code !== 0) {\n\t\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfile_list = [ new SFile(tar_file) ];\n\t\t\t}\n\t\t\t// 上書き保存\n\t\t\tcompress_file.remove(true);\n\t\t\tfor(let i = 0; i < file_list.length; i++) {\n\t\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" a \\\"\" + compress_file + \"\\\" \\\"\" + file_list[i] + \"\\\"\");\n\t\t\t\tif(result.exit_code !== 0) {\n\t\t\t\t\tif(temp_folder) {\n\t\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// targz の場合は、一時フォルダを削除\n\t\t\tif(temp_folder) {\n\t\t\t\ttemp_folder.remove();\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 展開する\n\t * - Windows標準の機能を使用して展開する( `zip` のみ対応)\n\t * - 外部ツール `7-Zip` がインストール/設定されている場合は、それを利用して展開する\n\t * \n\t * @param {SFile|string} input_file 展開したいファイル\n\t * @param {SFile|string} output_file 展開先のフォルダ\n\t * @returns {boolean} result\n\t */\n\tstatic extract(input_file, output_file) {\n\t\tlet extract_file = new SFile(input_file);\n\t\tconst extract_dir = new SFile(output_file);\n\t\tif(!extract_file.isFile() || !extract_dir.mkdirs()) {\n\t\t\treturn false;\n\t\t}\n\t\t// ファイルの拡張子を調べる\n\t\tlet comp_type;\n\t\tif(extract_file.getName().toLowerCase().endsWith(\".tar.gz\")) {\n\t\t\tcomp_type = \"targz\"\n\t\t}\n\t\telse {\n\t\t\tcomp_type = extract_file.getExtensionName().toLowerCase();\n\t\t}\n\t\t// 利用するツールを選択する\n\t\tconst tool_path = SFile.getCompressTool();\n\t\tif(tool_path === null) {\n\t\t\tif(comp_type === \"zip\") {\n\t\t\t\tconst shell = new ActiveXObject(\"Shell.Application\");\n\t\t\t\tconst FOF_SILENT = 0x4;\n\t\t\t\tconst FOF_NOCONFIRMATION = 0x10;\n\t\t\t\tshell.NameSpace(extract_dir.getAbsolutePath()).CopyHere(\n\t\t\t\t\tshell.NameSpace(extract_file.getAbsolutePath()).Items(),\n\t\t\t\t\tFOF_SILENT | FOF_NOCONFIRMATION\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tlet temp_folder = null;\n\t\t\t// targzの場合はgzの部分を先に回答する\n\t\t\tif(comp_type === \"targz\") {\n\t\t\t\ttemp_folder = SFile.createTempFile();\n\t\t\t\ttemp_folder.mkdirs();\n\t\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" x -y -o\\\"\" + temp_folder + \"\\\\\\\" \\\"\" + extract_file + \"\\\"\");\n\t\t\t\tif(result.exit_code !== 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// 中身は1つのtarファイルのみしか想定していない\n\t\t\t\tlet allfile = temp_folder.getAllFiles();\n\t\t\t\tif(allfile.length !== 1) {\n\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\textract_file = allfile[0];\n\t\t\t}\n\t\t\tconst command = \"\\\"\" + tool_path + \"\\\" x -y -o\\\"\" + extract_dir + \"\\\\\\\" \\\"\" + extract_file + \"\\\"\";\n\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" x -y -o\\\"\" + extract_dir + \"\\\\\\\" \\\"\" + extract_file + \"\\\"\");\n\t\t\tif(result.exit_code !== 0) {\n\t\t\t\tif(temp_folder) {\n\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(temp_folder) {\n\t\t\t\ttemp_folder.remove();\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 圧縮/展開用のツールを設定する\n\t * - このツールを利用して `compress`, `extract` が実行されます\n\t * - 未設定/未インストールの場合は、Windows標準の機能のみを利用し、`zip`のみ対応します\n\t * - `7-zip` のコマンドライン版 (`7za.exe`)のみ対応\n\t * @param {SFile|string} tool_path ツールのファイルパス\n\t * @returns {boolean} result\n\t */\n\t static setCompressTool(tool_path) {\n\t\tconst file = new SFile(tool_path);\n\t\tif(file.isFile() && /7za\\.exe/i.test(file.getName())) {\n\t\t\tSFile.COMPRESS_TOOL = file;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t }\n\n\t/**\n\t * 圧縮/展開用のツールを取得する\n\t * - このツールを利用して `compress`, `extract` が実行されます\n\t * - 未設定/未インストールの場合は、Windows標準の機能のみを利用し、`zip`のみ対応します\n\t * - 取得できない場合は `null` を返します\n\t * @returns {SFile|null} result\n\t */\n\t static getCompressTool() {\n\t\tif(SFile.COMPRESS_TOOL !== null) {\n\t\t\treturn SFile.COMPRESS_TOOL;\n\t\t}\n\t\tconst pgfile1 = new SFile(System.getEnvironmentString(\"ProgramFiles\") + \"\\\\7-Zip\\\\7z.exe\");\n\t\tif(pgfile1.isFile()) {\n\t\t\treturn pgfile1;\n\t\t}\n\t\tconst pgfile2 = new SFile(System.getEnvironmentString(\"ProgramFiles(x86)\") + \"\\\\7-Zip\\\\7z.exe\");\n\t\tif(pgfile2.isFile()) {\n\t\t\treturn pgfile2;\n\t\t}\n\t\treturn null;\n\t }\n\n}\n\n/**\n * 圧縮に使用するツール\n * @type {SFile}\n * @private\n */\n// @ts-ignore\nSFile.COMPRESS_TOOL = null;\n\n", + "content": "/**\n * The script is part of SenkoWSH.\n * \n * AUTHOR:\n * natade (http://twitter.com/natadea)\n * \n * LICENSE:\n * The MIT license https://opensource.org/licenses/MIT\n */\n\nimport Polyfill from \"./polyfill/Polyfill.js\";\nimport Format from \"./Format.js\";\nimport System from \"./System.js\";\n \n/**\n * ファイル/フォルダ/URLを扱うクラス\n */\nexport default class SFile {\n\n\t/**\n\t * 初期化\n\t * @param {string|SFile} pathname ファイル名/フォルダ名/URLアドレス\n\t */\n\tconstructor(pathname) {\n\t\tif(arguments.length !== 1) {\n\t\t\tthrow \"IllegalArgumentException\";\n\t\t}\n\n\t\t/**\n\t\t * @type {string}\n\t\t * @private\n\t\t */\n\t\tthis.pathname = \"\";\n\n\t\tif((typeof pathname === \"string\")||(pathname instanceof String)) {\n\t\t\t// \\を/に置き換える\n\t\t\tthis.pathname = pathname.replace(/\\\\/g, \"/\" );\n\t\t}\n\t\t// (pathname instanceof SFile) が反応しない場合があるので以下を利用\n\t\telse if((pathname instanceof Object) && (\"getAbsolutePath\" in pathname)) {\n\t\t\tthis.pathname = pathname.getAbsolutePath();\n\t\t}\n\t\telse {\n\t\t\tthrow \"IllegalArgumentException\";\n\t\t}\n\t\t\n\t\t/**\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.is_http = /^htt/.test(this.pathname);\n\n\t\t/**\n\t\t * @type {any}\n\t\t * @private\n\t\t */\n\t\tthis.fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t}\n\n\t/**\n\t * ファイルの削除(ゴミ箱には入りません)\n\t * @param {boolean} [is_force=false] - 読み取り専用でも削除する\n\t * @returns {boolean}\n\t */\n\tremove(is_force) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\ttry {\n\t\t\tif(this.isFile()) {\n\t\t\t\treturn this.fso.DeleteFile(this.pathname, is_force ? is_force : false );\n\t\t\t}\n\t\t\telse if(this.isDirectory()) {\n\t\t\t\treturn this.fso.DeleteFolder(this.pathname, is_force ? is_force : false );\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイルが存在するか\n\t * @returns {boolean}\n\t */\n\texists() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tlet out = this.isFile();\n\t\tif(out === false) {\n\t\t\tout = this.isDirectory();\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * ファイルのコピー\n\t * @param {string|SFile} file_obj\n\t * @returns {boolean}\n\t */\n\tcopy(file_obj) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst file = new SFile(file_obj);\n\t\tif(this.isFile()) {\n\t\t\treturn this.fso.CopyFile(this.pathname, file.getAbsolutePath(), true);\n\t\t}\n\t\telse if(this.isDirectory()) {\n\t\t\treturn this.fso.CopyFolder(this.pathname, file.getAbsolutePath(), true);\n\t\t}\n\t\telse {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイルの移動\n\t * - 移動後の `this` は、移動後のファイルを指す\n\t * - `this` がファイルの場合、ディレクトリを選択すると、ディレクトリ内へファイルを移動させます\n\t * - `this` がファイルの場合、ファイルを選択すると、ディレクトリの移動かつファイル名を変更します\n\t * - `this` がディレクトリの場合、指定したディレクトリへファイルを移動させるため、ディレクトリ名の変更は行えません\n\t * \n\t * @param {string|SFile} file_obj - 移動先のファイル名及びディレクトリ\n\t * @returns {boolean}\n\t */\n\tmove(file_obj) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst folder = new SFile(file_obj);\n\t\ttry {\n\t\t\tif(this.isFile()) {\n\t\t\t\tif(!folder.isDirectory()) {\n\t\t\t\t\t// ディレクトリを指していない場合は、移動 + ファイル名の変更\n\t\t\t\t\tthis.fso.MoveFile(this.pathname, folder.getAbsolutePath());\n\t\t\t\t\tthis.pathname = folder.getAbsolutePath();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// 宛先がディレクトリ内へ移動になる\n\t\t\t\t\tthis.fso.MoveFile(this.pathname, folder.getAbsolutePath() + \"\\\\\");\n\t\t\t\t\tthis.pathname = folder.getAbsolutePath() + \"/\" + this.getName();\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if(this.isDirectory()) {\n\t\t\t\t// フォルダを指定したフォルダ内へ移動\n\t\t\t\tthis.fso.MoveFolder(this.getAbsolutePath(), folder.getAbsolutePath() + \"/\");\n\t\t\t\tthis.pathname = folder.getAbsolutePath() + \"/\" + this.getName();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイル名を変更\n\t * - 変更後の `this` は、変更後のファイルを指す\n\t * - 引数はフルパスを渡した場合でもファイル名のみ使用する\n\t * \n\t * @param {string|SFile} file_obj 変更後のファイル名\n\t * @returns {boolean}\n\t */\n\trenameTo(file_obj) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\t// `GetFile` や `GetFolder` のプロパティ `.Name` で名前を変更した場合、\n\t\t// 例えばファイル名を大文字から小文字に変更すると\n\t\t// `Scripting.FileSystemObject` の仕様によりエラーが発生する\n\t\t// そのため `MoveFile`, `MoveFolder` を使用する\n\t\ttry {\n\t\t\t// getAbsolutePath で取得すると同一名のファイルが正しく取得できないので\n\t\t\t// 直接作成する\n\t\t\tconst dst = this.getParent() + \"\\\\\" + new SFile(file_obj).getName();\n\t\t\tif(this.isFile()) {\n\t\t\t\tthis.fso.MoveFile(this.getAbsolutePath(), dst);\n\t\t\t}\n\t\t\telse if(this.isDirectory()) {\n\t\t\t\tthis.fso.MoveFolder(this.getAbsolutePath(), dst);\n\t\t\t}\n\t\t\tthis.pathname = new SFile(dst).getAbsolutePath();\n\t\t\treturn true;\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 文字列化\n\t * @returns {string}\n\t */\n\ttoString() {\n\t\treturn this.getAbsolutePath();\n\t}\n\n\t/**\n\t * 名前を取得\n\t * @returns {string}\n\t */\n\tgetName() {\n\t\tif(this.is_http) {\n\t\t\t// 最後がスラッシュで終えている場合は、ファイル名取得できない\n\t\t\tif(this.isDirectory()) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tconst slashsplit = this.pathname.split(\"/\");\n\t\t\treturn slashsplit[slashsplit.length - 1];\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.GetFileName(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * 親フォルダの絶対パス\n\t * - 通常のフォルダの場合は、最後の「`/`」は除去される\n\t * - URLなら最後にスラッシュをつけて返す\n\t * \n\t * @returns {string} \n\t */\n\tgetParent() {\n\t\tif(this.is_http) {\n\t\t\tlet path = this.getAbsolutePath();\n\t\t\t// 最後がスラッシュの場合でホスト名のみの場合は、これ以上辿れない。\n\t\t\tif(/^http[^/]+\\/\\/[^/]+\\/$/.test(path)) {\n\t\t\t\treturn path\n\t\t\t}\n\t\t\t// 最後がスラッシュの場合はスラッシュを除去\n\t\t\tif(/\\/$/.test(path)) {\n\t\t\t\tpath = path.substring(0 ,path.length - 1);\n\t\t\t}\n\t\t\t// フォルダ名までを削る\n\t\t\treturn path.match(/^.*\\//)[0];\n\t\t}\n\t\telse {\n\t\t\t// フォルダ名までのパスを取得する\n\t\t\tlet path = this.getAbsolutePath().match(/.*[/\\\\]/)[0];\n\t\t\t// フォルダを削る\n\t\t\tpath = path.substring(0 ,path.length - 1);\n\t\t\treturn path;\n\t\t}\n\t}\n\n\t/**\n\t * 親フォルダ\n\t * @returns {SFile}\n\t */\n\tgetParentFile() {\n\t\treturn new SFile(this.getParent());\n\t}\n\n\t/**\n\t * 拡張子(ドットを含まない)\n\t * @returns {string}\n\t */\n\tgetExtensionName() {\n\t\tif(this.is_http) {\n\t\t\tconst dotlist = this.getName().split(\".\");\n\t\t\treturn dotlist[dotlist.length - 1];\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.GetExtensionName(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * 絶対パスかどうか\n\t * @returns {boolean}\n\t */\n\tisAbsolute() {\n\t\tif(this.is_http) {\n\t\t\treturn this.getAbsolutePath() === this.pathname;\n\t\t}\n\t\telse {\n\t\t\tconst name = this.pathname.replace(\"/\", \"\\\\\");\n\t\t\treturn this.fso.GetAbsolutePathName(this.pathname) === name;\n\t\t}\n\t}\n\n\t/**\n\t * フォルダかどうか\n\t * @returns {boolean}\n\t */\n\tisDirectory() {\n\t\tif(this.is_http) {\n\t\t\t// 最後がスラッシュで終えている場合はディレクトリ\n\t\t\treturn /\\/$/.test(this.pathname);\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.FolderExists(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * ファイルかどうか\n\t * @returns {boolean}\n\t */\n\tisFile() {\n\t\tif(this.is_http) {\n\t\t\t// 最後がスラッシュで終えていない場合はファイル\n\t\t\treturn /[^/]$/.test(this.pathname);\n\t\t}\n\t\telse {\n\t\t\treturn this.fso.FileExists(this.pathname);\n\t\t}\n\t}\n\n\t/**\n\t * 読み取り専用ファイルかどうか\n\t * @returns {boolean}\n\t */\n\tisReadOnly() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst ATTRIBUTES_READONLY = 1;\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\treturn (file.Attributes & ATTRIBUTES_READONLY) !== 0;\n\t}\n\t\n\t/**\n\t * 読み取り専用ファイルかどうかを設定する\n\t * @param {boolean} is_readonly\n\t * @param {boolean} [is_allfiles=false]\n\t * @returns {boolean}\n\t */\n\tsetReadOnly(is_readonly, is_allfiles) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst ATTRIBUTES_READONLY = 1;\n\t\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\t\tif(is_readonly) {\n\t\t\t\tfile.Attributes = file.Attributes | ATTRIBUTES_READONLY;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfile.Attributes = file.Attributes & ~ATTRIBUTES_READONLY;\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t\tif(this.isFile() || !is_allfiles) {\n\t\t\treturn true;\n\t\t}\n\t\tlet ret = true;\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tret = ret && file.setReadOnly(is_readonly, false);\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn ret;\n\t}\n\n\t/**\n\t * 隠しファイルかどうか\n\t * @returns {boolean}\n\t */\n\tisHidden() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst ATTRIBUTES_HIDDEN = 2;\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\treturn (file.Attributes & ATTRIBUTES_HIDDEN) !== 0;\n\t}\n\t\n\t/**\n\t *隠しファイルかどうかを設定する\n\t * @param {boolean} is_hidden\n\t * @param {boolean} [is_allfiles=false]\n\t * @returns {boolean}\n\t */\n\tsetHidden(is_hidden, is_allfiles) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst ATTRIBUTES_HIDDEN = 2;\n\t\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\t\tif(is_hidden) {\n\t\t\t\tfile.Attributes = file.Attributes | ATTRIBUTES_HIDDEN;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfile.Attributes = file.Attributes & ~ATTRIBUTES_HIDDEN;\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t\tif(this.isFile() || !is_allfiles) {\n\t\t\treturn true;\n\t\t}\n\t\tlet ret = true;\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tret = ret && file.setHidden(is_hidden, false);\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn ret;\n\t}\n\n\t/**\n\t * 更新日を取得\n\t * @returns {Date}\n\t */\n\tlastModified() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn null;\n\t\t}\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\t// DateLastModified は VT_DATE 値なので変換する\n\t\treturn new Date(file.DateLastModified);\n\t}\n\n\t/**\n\t * 更新日を設定(ファイルのみ対応)\n\t * @param {Date} date\n\t * @returns {boolean}\n\t */\n\tsetLastModified(date) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile()) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst shell = new ActiveXObject(\"Shell.Application\");\n\t\t\tconst folder = shell.NameSpace(this.getParent());\n\t\t\tconst file = folder.ParseName(this.getName());\n\t\t\tconst date_string = Format.datef(\"YYYY/MM/DD hh:mm:ss\", date);\n\t\t\tfile.ModifyDate = date_string;\n\t\t\treturn true;\n\t\t}\n\t\tcatch (e) {\n\t\t\tconsole.log(e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * ファイルサイズ\n\t * @returns {number}\n\t */\n\tlength() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile() && !this.isDirectory()) {\n\t\t\treturn -1;\n\t\t}\n\t\tconst file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname);\n\t\treturn file.Size;\n\t}\n\n\t/**\n\t * 配下のファイル名の一覧を取得\n\t * @returns {string[]}\n\t */\n\tgetFiles() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn null;\n\t\t}\n\t\tconst out = [];\n\t\tconst list = new Enumerator(this.fso.GetFolder(this.pathname).Files);\n\t\tfor(let i = 0; !list.atEnd(); list.moveNext()) {\n\t\t\tout[i++] = list.item().Name;\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 配下のサブフォルダ名の一覧を取得\n\t * @returns {string[]}\n\t */\n\tgetSubFolders() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn null;\n\t\t}\n\t\tconst out = [];\n\t\tconst list = new Enumerator(this.fso.GetFolder(this.pathname).SubFolders);\n\t\tfor(let i = 0; !list.atEnd(); list.moveNext()) {\n\t\t\tout[i++] = list.item().Name;\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 区切り文字と終端を正規化した文字列を取得\n\t * @returns {string}\n\t */\n\tgetNormalizedPathName() {\n\t\tif(this.pathname === \"\") {\n\t\t\treturn \".\\\\\";\n\t\t}\n\t\tlet name = this.pathname.replace(/\\//g, \"\\\\\");\n\t\tif(name.slice(-1) !== \"\\\\\") {\n\t\t\tname += \"\\\\\";\n\t\t}\n\t\treturn name;\n\t}\n\n\t/**\n\t * 配下のファイル名とフォルダ名を取得\n\t * @returns {string[]}\n\t */\n\tlist() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn null;\n\t\t}\n\t\tconst files = this.getFiles();\n\t\tconst subfolders = this.getSubFolders();\n\t\tconst out = [];\n\t\tfor(let j = 0; j < subfolders.length;) {\n\t\t\tout.push(subfolders[j++]);\n\t\t}\n\t\tfor(let j = 0; j < files.length;) {\n\t\t\tout.push(files[j++]);\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 絶対パスを取得\n\t * @returns {string}\n\t */\n\tgetAbsolutePath() {\n\t\tif(this.is_http) {\n\t\t\t// ホストとファイルに分ける\n\t\t\tconst hosttext = this.pathname.match(/^http[^/]+\\/\\/[^/]+\\//)[0];\n\t\t\tconst filetext = this.pathname.substr(hosttext.length);\n\t\t\t// パスを1つずつ解析しながら辿っていく\n\t\t\tlet name = hosttext;\n\t\t\tconst namelist = filetext.split(\"/\");\n\t\t\tlet i;\n\t\t\tfor(i = 0; i < namelist.length; i++) {\n\t\t\t\tif((namelist[i] === \"\") || (namelist[i] === \".\")) {\n\t\t\t\t\t// 階層は移動しない\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(namelist[i] === \"..\") {\n\t\t\t\t\t// 上の階層へ移動する\n\t\t\t\t\tname = name.substring(0 ,name.length - 1).match(/.*\\//)[0];\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// フォルダ名 + \"/\"\n\t\t\t\tname += namelist[i];\n\t\t\t\tif(i !== namelist.length - 1) {\n\t\t\t\t\tname += \"/\";\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn name;\n\t\t}\n\t\telse {\n\t\t\t// `*:` という2文字のパスで `C` 以外を設定した場合に正しいパスを設定できない不具合がある\n\t\t\t// 従って、防止用に、最後にコロンが付いている場合は\"C:\"とかなので\"C:/\"としてからパスを変換する\n\t\t\tif(/:$/.test(this.pathname)) {\n\t\t\t\treturn this.fso.GetAbsolutePathName(this.pathname + \"\\\\\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn this.fso.GetAbsolutePathName(this.pathname);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * フォルダを作成\n\t * - フォルダは1つのみ指定可能\n\t * - すでにフォルダがある場合はエラーを返す。\n\t * @returns {boolean}\n\t */\n\tmkdir() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst filename = this.getAbsolutePath();\n\t\tif(this.fso.FileExists(filename)) {\n\t\t\t// ファイルがあるため、フォルダを作れない\n\t\t\treturn false;\n\t\t}\n\t\telse if(this.fso.FolderExists(filename)) {\n\t\t\t// フォルダが既にあるため、TRUEで返す\n\t\t\treturn true;\n\t\t}\n\t\t// フォルダがないので作成する\n\t\tthis.fso.CreateFolder(filename);\n\t\t// 10秒間作られるまで待つ\n\t\tfor(let i = 0; i < (20 * 10); i++) {\n\t\t\tif(this.fso.FolderExists(filename)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tWScript.Sleep(50); // 50ms\n\t\t}\n\t\t// いつまで待ってもフォルダが作られないので失敗\n\t\treturn false;\n\t}\n\n\t/**\n\t * フォルダを作成\n\t * - 作成したいフォルダを続けて記載が可能\n\t * - フォルダがない場合はフォルダを作成していく\n\t * @returns {boolean}\n\t */\n\tmkdirs() {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst name = this.pathname.replace(/\\//g, \"\\\\\").split(\"\\\\\");\n\t\tlet dir = \"\";\n\t\tfor(let i = 0; i < name.length; i++) {\n\t\t\tdir += name[i];\n\t\t\tif(!(new SFile(dir)).mkdir()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdir += \"\\\\\";\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 実行ファイルを起動する\n\t * @param {number} [style=1] - 起動オプション\n\t * @param {boolean} [is_wait=false] - プロセスが終了するまで待つ\n\t * @returns {void}\n\t */\n\trun(style, is_wait) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst NormalFocus = 1;\n\t\tconst intWindowStyle = style !== undefined ? style : NormalFocus;\n\t\tconst bWaitOnReturn = is_wait !== undefined ? is_wait : false;\n\t\tconst objWShell = new ActiveXObject(\"WScript.Shell\");\n\t\t// @ts-ignore\n\t\tobjWShell.Run(this.getAbsolutePath(), intWindowStyle, bWaitOnReturn);\n\t}\n\n\t/**\n\t * 1行書き加える\n\t * @param {string} text\n\t * @returns {boolean}\n\t */\n\twriteLine(text) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tlet file;\n\t\tif(this.isFile()) {\n\t\t\tconst ForAppending = 8;\n\t\t\tfile = this.fso.OpenTextFile(this.pathname, ForAppending);\n\t\t}\n\t\telse if(this.isDirectory()) {\n\t\t\treturn false;\n\t\t}\n\t\telse {\n\t\t\tfile = this.fso.CreateTextFile(this.pathname, true);\n\t\t}\n\t\tfile.WriteLine(text);\n\t\tfile.Close();\n\t\treturn true;\n\t}\n\n\t/**\n\t * ローカル、インターネット上のファイルをテキストとして開く\n\t * - 改行コードは `\\n` に統一されます\n\t * \n\t * @param {string} [charset=\"_autodetect_all\"] - 文字コード\n\t * @returns {string} 失敗時は null\n\t */\n\tgetTextFile(charset) {\n\t\tconst icharset = charset !== undefined ? charset : \"_autodetect_all\";\n\t\tconst inewline = \"\\n\"; //javascript上での改行\n\t\tlet text = null;\n\t\tif(/^htt/.test(this.pathname)) {\n\t\t\tconst http = System.createXMLHttpRequest();\n\t\t\tif(http === null) {\n\t\t\t\tconsole.log(\"createXMLHttpRequest\")\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thttp.open(\"GET\", this.pathname, false);\n\t\t\ttry {\n\t\t\t\thttp.send(null);\n\t\t\t\tif(http.status === 200) {\n\t\t\t\t\ttext = http.responseText;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.log(\"HTTP status codes \" + http.status);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst is_fso = /shift_jis|sjis|ascii|unicode|utf-16le/i.test(icharset);\n\t\t\tif(is_fso) {\n\t\t\t\t// Scripting.FileSystemObject で開く\n\t\t\t\t// 入出力モード = 読取専用モード\n\t\t\t\tconst ForReading = 1;\n\t\t\t\tconst mode = ForReading;\n\t\t\t\t// ファイルの新規作成 = 新規作成しない\n\t\t\t\tconst option = false;\n\t\t\t\t// 文字のエンコード\n\t\t\t\tconst TristateFalse\t\t\t= 0;\t// ASCII(Shift-JIS)\n\t\t\t\tconst TristateTrue\t\t\t= -1;\t// Unicode(UTF-16)\n\t\t\t\tconst TristateUseDefault\t= -2;\t// システムの規定値\n\t\t\t\tlet tristate = 0;\n\t\t\t\tif(/ascii/i.test(icharset)) {\n\t\t\t\t\t// ASCII\n\t\t\t\t\ttristate = TristateFalse;\n\t\t\t\t}\n\t\t\t\telse if(/shift_jis|sjis/i.test(icharset)) {\n\t\t\t\t\t// システムのデフォルト(日本語のOSだと仮定)\n\t\t\t\t\ttristate = TristateUseDefault;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// utf-16le\n\t\t\t\t\ttristate = TristateTrue;\n\t\t\t\t}\n\t\t\t\tconst open_file = this.fso.OpenTextFile(this.pathname, mode, option, tristate );\n\t\t\t\ttext = open_file.ReadAll();\n\t\t\t\topen_file.Close();\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// 自由な文字エンコードで開く(速度は遅い)\n\t\t\t\t// 使用可能な charset については下記を参照\n\t\t\t\t// HKEY_CLASSES_ROOT\\MIME\\Database\\Charset\n\t\t\t\tconst adTypeText = 2;\n\t\t\t\tconst adReadAll = -1;\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = icharset;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\ttext = stream.readText(adReadAll);\n\t\t\t\tstream.close();\n\t\t\t\t// 文字コードが自動取得の場合、BOMまで読み込んでしまうのを防止する\n\t\t\t\tif((icharset === \"_autodetect_all\")||(icharset === \"_autodetect\")) {\n\t\t\t\t\tlet newcharset = \"\";\n\t\t\t\t\t// 1文字以上のとき\n\t\t\t\t\tif(text.length > 1) {\n\t\t\t\t\t\t// utf-16le\n\t\t\t\t\t\tif(text.charCodeAt(0) === 0xfeff) {\n\t\t\t\t\t\t\t// 通常は、このルートはBOM付きutf-16leのときに通るが、\n\t\t\t\t\t\t\t// BOM付きutf-8でも通る場合がなぜかある。(後述)\n\t\t\t\t\t\t\tnewcharset = \"unicode\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// utf-16be\n\t\t\t\t\t\telse if(text.charCodeAt(0) === 0xfffe) {\n\t\t\t\t\t\t\tnewcharset = \"unicodeFFFE\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 2文字以上のとき\n\t\t\t\t\tif(text.length > 2) {\n\t\t\t\t\t\t// BOM付きutf-8でなぜかこの文字がくっつく場合がある。\n\t\t\t\t\t\tif(\t(text.charCodeAt(0) === 0x30fb) &&\n\t\t\t\t\t\t\t(text.charCodeAt(1) === 0xff7f)) {\n\t\t\t\t\t\t\tnewcharset = \"utf-8\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 3文字以上のとき\n\t\t\t\t\tif(text.length > 3) {\n\t\t\t\t\t\t// utf-8\n\t\t\t\t\t\tif(\t(text.charCodeAt(0) === 0xef) &&\n\t\t\t\t\t\t\t(text.charCodeAt(1) === 0xbb) &&\n\t\t\t\t\t\t\t(text.charCodeAt(2) === 0xbf)) {\n\t\t\t\t\t\t\tnewcharset = \"utf-8\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 上判定でBOM付きが分かった場合、正しい文字コードで取得する\n\t\t\t\t\tif(newcharset !== \"\") {\n\t\t\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\t\t\tstream.type = adTypeText;\n\t\t\t\t\t\tstream.charset = newcharset;\n\t\t\t\t\t\tstream.open();\n\t\t\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\t\t\ttext = stream.readText(adReadAll);\n\t\t\t\t\t\tstream.close();\n\t\t\t\t\t}\n\t\t\t\t\t// BOM付きutf-8 でも BOM付きutf-16le と判定した場合の対処\n\t\t\t\t\tif((text.length > 1) && (text.charCodeAt(0) === 0xbbef)) {\n\t\t\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\t\t\tstream.type = adTypeText;\n\t\t\t\t\t\tstream.charset = \"utf-8\";\n\t\t\t\t\t\tstream.open();\n\t\t\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\t\t\ttext = stream.readText(adReadAll);\n\t\t\t\t\t\tstream.close();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(text !== null) {\n\t\t\treturn text.replace(/\\r\\n?|\\n/g, inewline); //改行コードを統一\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * テキストファイルを保存\n\t * @param {string} text\n\t * @param {string} [charset=\"utf-8\"] - 文字コード\n\t * @param {string} [newline=\"\\n\"] - 改行コード\n\t * @param {boolean} [issetBOM=true] - BOMの有無(`utf-8`のみ有効 )\n\t * @returns {boolean}\n\t */\n\tsetTextFile(text, charset, newline, issetBOM) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tconst icharset = charset !== undefined ? charset : \"utf-8\";\n\t\tconst inewline = newline !== undefined ? newline : \"\\n\";\n\t\tconst iissetBOM = issetBOM !== undefined ? issetBOM : true; //utf-8のみ有効 BOMありかなし\n\t\tconst is_fso = /shift_jis|sjis|ascii|unicode|utf-16le/i.test(icharset);\n\t\tif(is_fso) {\n\t\t\t// Scripting.FileSystemObject で書き込む\n\t\t\t// 入出力モード = 上書きモード\n\t\t\tconst ForWriting = 2;\n\t\t\tconst mode = ForWriting;\n\t\t\t// ファイルの新規作成 = 作成\n\t\t\tconst option = true;\n\t\t\t// 文字のエンコード\n\t\t\tconst TristateFalse\t\t\t= 0;\t// ASCII(Shift-JIS)\n\t\t\tconst TristateTrue\t\t\t= -1;\t// Unicode(UTF-16)\n\t\t\tconst TristateUseDefault\t= -2;\t// システムの規定値\n\t\t\tlet tristate = 0;\n\t\t\tif(/ascii/i.test(icharset)) {\n\t\t\t\t// ASCII\n\t\t\t\ttristate = TristateFalse;\n\t\t\t}\n\t\t\telse if(/shift_jis|sjis/i.test(icharset)) {\n\t\t\t\t// システムのデフォルト(日本語のOSだと仮定)\n\t\t\t\ttristate = TristateUseDefault;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// utf-16le\n\t\t\t\ttristate = TristateTrue;\n\t\t\t}\n\t\t\tconst open_file = this.fso.OpenTextFile(this.pathname, mode, option, tristate );\n\t\t\topen_file.Write(text.replace(/\\r\\n?|\\n/g, inewline));\n\t\t\topen_file.Close();\n\t\t}\n\t\telse {\n\t\t\t// ADODB.Streamで書き込む\n\t\t\tconst adTypeBinary = 1;\n\t\t\tconst adTypeText = 2;\n\t\t\tconst adSaveCreateOverWrite = 2;\n\t\t\ttry {\n\t\t\t\t// 使用可能な charset については下記を参照\n\t\t\t\t// HKEY_CLASSES_ROOT\\MIME\\Database\\Charset\n\t\t\t\tlet stream;\n\t\t\t\tstream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = icharset;\n\t\t\t\tstream.open();\n\t\t\t\tstream.writeText(text.replace(/\\r\\n?|\\n/g, inewline)); //改行コードを統一\n\t\t\t\tif(/utf-8/.test(icharset.toLowerCase()) && (!iissetBOM)) {\n\t\t\t\t\t// バイナリ型にして3バイト目以降をバイト型で取得\n\t\t\t\t\tstream.position = 0;\n\t\t\t\t\tstream.type = adTypeBinary;\n\t\t\t\t\tstream.position = 3;\n\t\t\t\t\tconst binary = stream.read();\n\t\t\t\t\tstream.close();\n\t\t\t\t\t// 取得したバイナリデータを1バイト目から書きこむ\n\t\t\t\t\tstream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\t\tstream.type = adTypeBinary;\n\t\t\t\t\tstream.open();\n\t\t\t\t\tstream.write(binary);\n\t\t\t\t}\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * ローカル、インターネット上のファイルをバイナリとして開く\n\t * - 参考速度:0.5 sec/MB\n\t * - 巨大なファイルの一部を調べる場合は、位置とサイズを指定した方がよい\n\t * \n\t * @param {number} [offset] - 位置(※ 指定すると速度が低下する)\n\t * @param {number} [size] - サイズ(※ 指定すると速度が低下する)\n\t * @returns {number[]}\n\t */\n\tgetBinaryFile(offset, size) {\n\t\tif(/^htt/.test(this.pathname)) {\n\t\t\tconst http = System.createXMLHttpRequest();\n\t\t\tif(http === null) {\n\t\t\t\tconsole.log(\"createXMLHttpRequest\")\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thttp.open(\"GET\", this.pathname, false);\n\t\t\tlet byte_array = null;\n\t\t\ttry {\n\t\t\t\thttp.send(null);\n\t\t\t\tif(http.status === 200) {\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tbyte_array = http.responseBody;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.log(\"HTTP status codes \" + http.status);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn System.createNumberArrayFromByteArray(byte_array);\n\t\t}\n\t\t// 位置を無指定\n\t\tif(offset === undefined) {\n\t\t\tconst adTypeText = 2;\n\t\t\tconst adReadAll = -1;\n\t\t\tconst charset = \"iso-8859-1\";\n\t\t\t/**\n\t\t\t * @type {Object}\n\t\t\t * @private\n\t\t\t */\n\t\t\tconst map = {\n\t\t\t\t0x20AC\t:\t0x80\t,\t//\t8364\t128\n\t\t\t\t0x201A\t:\t0x82\t,\t//\t8218\t130\n\t\t\t\t0x0192\t:\t0x83\t,\t//\t402\t131\n\t\t\t\t0x201E\t:\t0x84\t,\t//\t8222\t132\n\t\t\t\t0x2026\t:\t0x85\t,\t//\t8230\t133\n\t\t\t\t0x2020\t:\t0x86\t,\t//\t8224\t134\n\t\t\t\t0x2021\t:\t0x87\t,\t//\t8225\t135\n\t\t\t\t0x02C6\t:\t0x88\t,\t//\t710\t136\n\t\t\t\t0x2030\t:\t0x89\t,\t//\t8240\t137\n\t\t\t\t0x0160\t:\t0x8A\t,\t//\t352\t138\n\t\t\t\t0x2039\t:\t0x8B\t,\t//\t8249\t139\n\t\t\t\t0x0152\t:\t0x8C\t,\t//\t338\t140\n\t\t\t\t0x017D\t:\t0x8E\t,\t//\t381\t142\n\t\t\t\t0x2018\t:\t0x91\t,\t//\t8216\t145\n\t\t\t\t0x2019\t:\t0x92\t,\t//\t8217\t146\n\t\t\t\t0x201C\t:\t0x93\t,\t//\t8220\t147\n\t\t\t\t0x201D\t:\t0x94\t,\t//\t8221\t148\n\t\t\t\t0x2022\t:\t0x95\t,\t//\t8226\t149\n\t\t\t\t0x2013\t:\t0x96\t,\t//\t8211\t150\n\t\t\t\t0x2014\t:\t0x97\t,\t//\t8212\t151\n\t\t\t\t0x02DC\t:\t0x98\t,\t//\t732\t152\n\t\t\t\t0x2122\t:\t0x99\t,\t//\t8482\t153\n\t\t\t\t0x0161\t:\t0x9A\t,\t//\t353\t154\n\t\t\t\t0x203A\t:\t0x9B\t,\t//\t8250\t155\n\t\t\t\t0x0153\t:\t0x9C\t,\t//\t339\t156\n\t\t\t\t0x017E\t:\t0x9E\t,\t//\t382\t158\n\t\t\t\t0x0178\t:\t0x9F\t\t//\t376\t159\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = charset;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\tconst text = stream.readText(adReadAll);\n\t\t\t\tstream.close();\n\t\t\t\tconst out = new Array(text.length);\n\t\t\t\tfor(let i = 0;i < text.length;i++) {\n\t\t\t\t\tconst x = text.charCodeAt(i);\n\t\t\t\t\tif(0xFF < x) {\n\t\t\t\t\t\tout[i] = map[x];\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tout[i] = x;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\ttry {\n\t\t\t\tconst filesize = this.length();\n\t\t\t\tif(filesize === -1) {\n\t\t\t\t\tconsole.log(\"filesize error\");\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\t// 位置を指定している場合\n\t\t\t\tif(offset < 0 || filesize <= offset) {\n\t\t\t\t\tconsole.log(\"offset error\");\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tconst ioffset = offset;\n\t\t\t\tlet isize = size !== undefined ? size : filesize - ioffset;\n\t\t\t\t// 長さのチェック\n\t\t\t\tif(filesize < (ioffset + isize) || isize < 0) {\n\t\t\t\t\tisize = filesize - ioffset;\n\t\t\t\t}\n\t\t\t\t// バイト配列を読み込む\n\t\t\t\tconst adTypeBinary = 1;\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.Type = adTypeBinary;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\tstream.position = ioffset;\n\t\t\t\tconst byte_array = stream.read(isize);\n\t\t\t\tstream.close();\n\t\t\t\treturn System.createNumberArrayFromByteArray(byte_array);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * バイナリファイルを保存\n\t * - 参考速度:1.0 sec/MB\n\t * \n\t * @param {number[]} array_\n\t * @param {number} [offset] - 位置(※ 指定すると速度が低下する)\n\t * @returns {boolean}\n\t */\n\tsetBinaryFile(array_, offset) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\t// 位置を無指定\n\t\tlet is_write = true;\n\t\tif((offset === undefined) || offset === 0) {\n\t\t\ttry {\n\t\t\t\tconst adTypeText = 2;\n\t\t\t\tconst adSaveCreateOverWrite = 2;\n\t\t\t\tconst charset = \"iso-8859-1\";\n\t\t\t\tconst buffersize = 1024 * 128;\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.type = adTypeText;\n\t\t\t\tstream.charset = charset;\n\t\t\t\tstream.open();\n\t\t\t\tfor(let i = 0;i < array_.length;) {\n\t\t\t\t\tconst text = [];\n\t\t\t\t\tfor(let j = 0; (j < buffersize) && (i < array_.length); j++, i++) {\n\t\t\t\t\t\ttext[j] = String.fromCharCode(array_[i]);\n\t\t\t\t\t}\n\t\t\t\t\tstream.writeText(text.join(\"\"));\n\t\t\t\t}\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\tis_write = false;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst adTypeBinary = 1;\n\t\t\tconst adSaveCreateOverWrite = 2;\n\t\t\tif(!this.isFile()) {\n\t\t\t\tconst byte_array = System.createByteArrayFromNumberArray(array_, offset);\n\t\t\t\tif(byte_array === null) {\n\t\t\t\t\tconsole.log(\"createByteArrayFromNumberArray\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.Type = adTypeBinary;\n\t\t\t\tstream.open();\n\t\t\t\tstream.write(byte_array);\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst byte_array = System.createByteArrayFromNumberArray(array_);\n\t\t\t\tif(byte_array === null) {\n\t\t\t\t\tconsole.log(\"createByteArrayFromNumberArray\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tconst stream = new ActiveXObject(\"ADODB.Stream\");\n\t\t\t\tstream.Type = adTypeBinary;\n\t\t\t\tstream.open();\n\t\t\t\tstream.loadFromFile(this.pathname);\n\t\t\t\tstream.position = offset;\n\t\t\t\tstream.write(byte_array);\n\t\t\t\tstream.saveToFile(this.pathname, adSaveCreateOverWrite);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t\tis_write = false;\n\t\t\t}\n\t\t}\n\t\treturn is_write;\n\t}\n\n\t/**\n\t * ファイルのハッシュ値を計算する\n\t * @param {string} [algorithm=\"MD5\"] - アルゴリズム\n\t * @returns {string} 半角英数の16進数で表したハッシュ値、失敗時は`\"0\"`\n\t */\n\tgetHashCode(algorithm) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isFile()) {\n\t\t\treturn \"0\";\n\t\t}\n\t\tconst algorithm_ = algorithm !== undefined ? algorithm : \"MD5\";\n\t\tconst message = \"certutil -hashfile \\\"\" + this.getAbsolutePath() + \"\\\" \" + algorithm_.toUpperCase();\n\t\tconst output = System.exec(message);\n\t\tif(output.exit_code !== 0) {\n\t\t\treturn \"0\";\n\t\t}\n\t\t// 2行目を抽出する\n\t\tconst hash_lines = output.out.split(/\\n/);\n\t\tif(hash_lines.length <= 1) {\n\t\t\treturn \"0\";\n\t\t}\n\t\t// 2種類のタイプを検知させる\n\t\t// - dcd802e3848075716e92424cfdcb9c0d (Windows 10)\n\t\t// - dc d8 02 e3 84 80 75 71 6e 92 42 4c fd cb 9c 0d (Windows8.1)\n\t\tconst hash = hash_lines[1].trim().toLowerCase().match(/^(([0-9a-f]{2}){8,})|((([0-9a-f]{2} ){7,})[0-9a-f]{2})$/);\n\t\tif(hash === null) {\n\t\t\treturn \"0\";\n\t\t}\n\t\treturn hash[0].replace(/ /g, \"\");\n\t}\n\n\t/**\n\t * テンポラリフォルダ内の適当なファイル名を取得\n\t * @returns {SFile}\n\t */\n\tstatic createTempFile() {\n\t\tconst TemporaryFolder = 2;\n\t\tconst fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t\t// テンポラリフォルダ内の適当なファイル名を取得します\n\t\treturn new SFile(fso.GetSpecialFolder(TemporaryFolder) + \"\\\\\" + fso.GetTempName());\n\t}\n\n\t/**\n\t * カレントディレクトリを取得\n\t * @returns {SFile}\n\t */\n\tstatic getCurrentDirectory() {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\treturn new SFile(shell.CurrentDirectory);\n\t}\n\n\t/**\n\t * カレントディレクトリを設定\n\t * @param {string|SFile} file_obj\n\t */\n\tstatic setCurrentDirectory(file_obj) {\n\t\tconst file = new SFile(file_obj);\n\t\tconst shell = WScript.CreateObject (\"WScript.Shell\");\n\t\tconst fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t\tshell.CurrentDirectory = fso.GetFolder(file.getAbsolutePath()).Name;\n\t}\n\n\t/**\n\t * フォルダの中のフォルダとファイルに対して指定した関数を実行する\n\t * @param {function(SFile): boolean} func 戻り値が`false`で処理を終了。\n\t * @returns {boolean} result\n\t */\n\teach(func) {\n\t\tif(this.is_http) {\n\t\t\tthrow \"IllegalMethod\";\n\t\t}\n\t\tif(!this.isDirectory) {\n\t\t\treturn func.call(func, this);\n\t\t}\n\t\tconst path = [];\n\t\tconst collection = [];\n\t\tlet file;\n\t\tlet pointer = 0;\n\t\tlet list;\n\t\tlet targetfolder;\n\t\tpath[pointer] = this.getNormalizedPathName();\n\n\t\t// 1階層目を処理する\n\t\ttargetfolder = this.fso.GetFolder(path[pointer]);\n\t\tlist = new Enumerator(this.fso.GetFolder(targetfolder).Files);\n\t\tfor(; !list.atEnd(); list.moveNext()) {\n\t\t\tfile = new SFile(path[pointer] + list.item().Name);\n\t\t\tif(!func.call(func, file)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// 2階層目以降を処理する\n\t\tif(targetfolder.SubFolders.Count === 0) {\n\t\t\treturn false;\n\t\t}\n\t\tcollection[pointer] = new Enumerator(targetfolder.SubFolders);\n\t\tpointer++;\n\t\twhile(true) {\n\t\t\tpath[pointer] = path[pointer - 1] + collection[pointer - 1].item().Name;\n\t\t\tfile = new SFile(path[pointer]);\n\t\t\tif(!func.call(func, file)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tpath[pointer] += \"\\\\\";\n\t\t\ttargetfolder = this.fso.GetFolder(path[pointer]);\n\t\t\tlist = new Enumerator(targetfolder.Files);\n\t\t\tfor(; !list.atEnd(); list.moveNext()) {\n\t\t\t\tfile = new SFile(path[pointer] + list.item().Name);\n\t\t\t\tif(!func.call(func, file)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(targetfolder.SubFolders.Count === 0) {\n\t\t\t\twhile(true) {\n\t\t\t\t\tif(pointer === 0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcollection[pointer - 1].moveNext();\n\t\t\t\t\tif(collection[pointer - 1].atEnd()) {\n\t\t\t\t\t\tpointer--;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(pointer === 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcollection[pointer] = new Enumerator(targetfolder.SubFolders);\n\t\t\t\tpointer++;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * サブフォルダの中まで探索して全てのファイルとフォルダを取得\n\t * @returns {SFile[]}\n\t */\n\tgetAllFiles() {\n\t\t/**\n\t\t * @type {SFile[]}\n\t\t */\n\t\tconst out = [];\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tout.push(file);\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\treturn out;\n\t}\n\n\t/**\n\t * 指定した条件にあうファイルを探す\n\t * - 関数を指定する場合は、ファイル名とフルパスが引数に渡されます\n\t * \n\t * @param {string|SFile|RegExp|function(SFile): boolean} file_obj\n\t * @param {boolean} [is_all_file=false] trueで指定した場合は条件に合うファイルを複数見つけて配列で返す\n\t * @returns {SFile|SFile[]|null}\n\t */\n\tsearchFile(file_obj, is_all_file) {\n\t\tconst is_all_file_ = is_all_file !== undefined ? is_all_file : false;\n\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t * @private\n\t\t */\n\t\tlet isTarget;\n\t\tif(typeof file_obj !== \"function\") {\n\t\t\tif(System.typeOf(file_obj) === \"regexp\") {\n\t\t\t\t/**\n\t\t\t\t * @type {RegExp}\n\t\t\t\t */\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst reg = file_obj;\n\t\t\t\tisTarget = function(file) {\n\t\t\t\t\tconst result = reg.exec(file.getAbsolutePath());\n\t\t\t\t\treturn result !== null;\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst file = new SFile(file_obj);\n\t\t\t\tconst buffer = file.getName();\n\t\t\t\tisTarget = function(file) {\n\t\t\t\t\treturn file.getName() === buffer;\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tisTarget = file_obj;\n\t\t}\n\t\t/**\n\t\t * @type {SFile}\n\t\t */\n\t\tlet target_file = null;\n\t\t/**\n\t\t * @type {SFile[]}\n\t\t */\n\t\tlet target_files = [];\n\t\t/**\n\t\t * @type {function(SFile): boolean}\n\t\t */\n\t\tconst func = function(file) {\n\t\t\tif(isTarget(file)) {\n\t\t\t\tif(is_all_file_) {\n\t\t\t\t\ttarget_files.push(file);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttarget_file = file;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\t\tthis.each(func);\n\t\tif(is_all_file_) {\n\t\t\treturn target_files;\n\t\t}\n\t\telse {\n\t\t\treturn target_file;\n\t\t}\n\t}\n\n\t/**\n\t * 圧縮する\n\t * - 圧縮後のファイル名の拡張子で圧縮したい形式を指定する\n\t * - Windows標準の機能を使用して圧縮する( `zip` のみ対応)\n\t * - 外部ツール `7-Zip` がインストール/設定されている場合は、それを利用して圧縮する\n\t * \n\t * @param {SFile|string|SFile[]|string[]} input_file 圧縮したいファイル\n\t * @param {SFile|string} output_file 圧縮後のファイル名\n\t * @returns {boolean} result\n\t */\n\tstatic compress(input_file, output_file) {\n\t\tconst compress_file = new SFile(output_file);\n\t\t// ファイルの拡張子を調べる\n\t\tlet comp_type = null;\n\t\tif(compress_file.getName().toLowerCase().endsWith(\".tar.gz\")) {\n\t\t\tcomp_type = \"targz\"\n\t\t}\n\t\telse {\n\t\t\tcomp_type = compress_file.getExtensionName().toLowerCase();\n\t\t}\n\t\t// 利用するツールを選択する\n\t\tconst tool_path = SFile.getCompressTool();\n\t\t// 圧縮したい対象のファイル一覧を作成\n\t\tconst file_list_buf = Array.isArray(input_file) ? input_file : [input_file];\n\t\t/**\n\t\t * @type {SFile[]}\n\t\t */\n\t\tlet file_list = [];\n\t\t// ファイルチェック\n\t\tfor(let i = 0;i < file_list_buf.length; i++) {\n\t\t\tfile_list[i] = new SFile(file_list_buf[i]);\n\t\t\tif(!(file_list[i].exists())) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t// 入力ファイル数が1つで拡張子がtarの場合\n\t\tif(file_list.length === 1 && file_list[0].getExtensionName().toLowerCase() === \"tar\") {\n\t\t\tcomp_type = compress_file.getExtensionName().toLowerCase();\n\t\t}\n\t\tif(tool_path === null) {\n\t\t\tif(comp_type === \"zip\") {\n\t\t\t\tconst shell = new ActiveXObject(\"Shell.Application\");\n\t\t\t\tconst fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\t\t\t\t// ZIPファイルを作成\n\t\t\t\tcompress_file.setBinaryFile([0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);\n\t\t\t\tconst zip = shell.NameSpace(compress_file.getAbsolutePath());\n\t\t\t\t// 1つずつデータを入れていく\n\t\t\t\tfor(let i = 0; i < file_list.length; i++) {\n\t\t\t\t\tconst name = file_list[i].getAbsolutePath();\n\t\t\t\t\tzip.CopyHere(name, 4);\n\t\t\t\t\t// コピーが終わるまで wait\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tSystem.sleep(0.1);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst ForAppending = 8;\n\t\t\t\t\t\t\tfso.OpenTextFile(compress_file.getAbsolutePath(), ForAppending).Close();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tlet temp_folder = null;\n\t\t\t// targzの場合はtarだけ作成する\n\t\t\tif(comp_type === \"targz\") {\n\t\t\t\ttemp_folder = SFile.createTempFile();\n\t\t\t\ttemp_folder.mkdirs();\n\t\t\t\tconst name = compress_file.getName();\n\t\t\t\tconst tar_file = temp_folder + \"\\\\\" + name.substr(0, name.length - \".tar.gz\".length ) + \".tar\";\n\t\t\t\tfor(let i = 0; i < file_list.length; i++) {\n\t\t\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" a \\\"\" + tar_file + \"\\\" \\\"\" + file_list[i] + \"\\\"\");\n\t\t\t\t\tif(result.exit_code !== 0) {\n\t\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfile_list = [ new SFile(tar_file) ];\n\t\t\t}\n\t\t\t// 上書き保存\n\t\t\tcompress_file.remove(true);\n\t\t\tfor(let i = 0; i < file_list.length; i++) {\n\t\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" a \\\"\" + compress_file + \"\\\" \\\"\" + file_list[i] + \"\\\"\");\n\t\t\t\tif(result.exit_code !== 0) {\n\t\t\t\t\tif(temp_folder) {\n\t\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// targz の場合は、一時フォルダを削除\n\t\t\tif(temp_folder) {\n\t\t\t\ttemp_folder.remove();\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 展開する\n\t * - Windows標準の機能を使用して展開する( `zip` のみ対応)\n\t * - 外部ツール `7-Zip` がインストール/設定されている場合は、それを利用して展開する\n\t * \n\t * @param {SFile|string} input_file 展開したいファイル\n\t * @param {SFile|string} output_file 展開先のフォルダ\n\t * @returns {boolean} result\n\t */\n\tstatic extract(input_file, output_file) {\n\t\tlet extract_file = new SFile(input_file);\n\t\tconst extract_dir = new SFile(output_file);\n\t\tif(!extract_file.isFile() || !extract_dir.mkdirs()) {\n\t\t\treturn false;\n\t\t}\n\t\t// ファイルの拡張子を調べる\n\t\tlet comp_type;\n\t\tif(extract_file.getName().toLowerCase().endsWith(\".tar.gz\")) {\n\t\t\tcomp_type = \"targz\"\n\t\t}\n\t\telse {\n\t\t\tcomp_type = extract_file.getExtensionName().toLowerCase();\n\t\t}\n\t\t// 利用するツールを選択する\n\t\tconst tool_path = SFile.getCompressTool();\n\t\tif(tool_path === null) {\n\t\t\tif(comp_type === \"zip\") {\n\t\t\t\tconst shell = new ActiveXObject(\"Shell.Application\");\n\t\t\t\tconst FOF_SILENT = 0x4;\n\t\t\t\tconst FOF_NOCONFIRMATION = 0x10;\n\t\t\t\tshell.NameSpace(extract_dir.getAbsolutePath()).CopyHere(\n\t\t\t\t\tshell.NameSpace(extract_file.getAbsolutePath()).Items(),\n\t\t\t\t\tFOF_SILENT | FOF_NOCONFIRMATION\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tlet temp_folder = null;\n\t\t\t// targzの場合はgzの部分を先に回答する\n\t\t\tif(comp_type === \"targz\") {\n\t\t\t\ttemp_folder = SFile.createTempFile();\n\t\t\t\ttemp_folder.mkdirs();\n\t\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" x -y -o\\\"\" + temp_folder + \"\\\\\\\" \\\"\" + extract_file + \"\\\"\");\n\t\t\t\tif(result.exit_code !== 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// 中身は1つのtarファイルのみしか想定していない\n\t\t\t\tlet allfile = temp_folder.getAllFiles();\n\t\t\t\tif(allfile.length !== 1) {\n\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\textract_file = allfile[0];\n\t\t\t}\n\t\t\tconst result = System.exec(\"\\\"\" + tool_path + \"\\\" x -y -o\\\"\" + extract_dir + \"\\\\\\\" \\\"\" + extract_file + \"\\\"\");\n\t\t\tif(result.exit_code !== 0) {\n\t\t\t\tif(temp_folder) {\n\t\t\t\t\ttemp_folder.remove();\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(temp_folder) {\n\t\t\t\ttemp_folder.remove();\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 圧縮/展開用のツールを設定する\n\t * - このツールを利用して `compress`, `extract` が実行されます\n\t * - 未設定/未インストールの場合は、Windows標準の機能のみを利用し、`zip`のみ対応します\n\t * - `7-zip` のコマンドライン版 (`7za.exe`)のみ対応\n\t * @param {SFile|string} tool_path ツールのファイルパス\n\t * @returns {boolean} result\n\t */\n\t static setCompressTool(tool_path) {\n\t\tconst file = new SFile(tool_path);\n\t\tif(file.isFile() && /7za\\.exe/i.test(file.getName())) {\n\t\t\tSFile.COMPRESS_TOOL = file;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t }\n\n\t/**\n\t * 圧縮/展開用のツールを取得する\n\t * - このツールを利用して `compress`, `extract` が実行されます\n\t * - 未設定/未インストールの場合は、Windows標準の機能のみを利用し、`zip`のみ対応します\n\t * - 取得できない場合は `null` を返します\n\t * @returns {SFile|null} result\n\t */\n\t static getCompressTool() {\n\t\tif(SFile.COMPRESS_TOOL !== null) {\n\t\t\treturn SFile.COMPRESS_TOOL;\n\t\t}\n\t\tconst pgfile1 = new SFile(System.getEnvironmentString(\"ProgramFiles\") + \"\\\\7-Zip\\\\7z.exe\");\n\t\tif(pgfile1.isFile()) {\n\t\t\treturn pgfile1;\n\t\t}\n\t\tconst pgfile2 = new SFile(System.getEnvironmentString(\"ProgramFiles(x86)\") + \"\\\\7-Zip\\\\7z.exe\");\n\t\tif(pgfile2.isFile()) {\n\t\t\treturn pgfile2;\n\t\t}\n\t\treturn null;\n\t }\n\n}\n\n/**\n * 圧縮に使用するツール\n * @type {SFile}\n * @private\n */\n// @ts-ignore\nSFile.COMPRESS_TOOL = null;\n\n", "static": true, "longname": "D:/JavaScript/SenkoWSH/src/senko/SFile.js", "access": "public", @@ -7140,8 +7140,8 @@ "static": false, "longname": "src/senko/SFile.js~SFile#move", "access": "public", - "description": "ファイルの移動", - "lineNumber": 124, + "description": "ファイルの移動\n- 移動後の `this` は、移動後のファイルを指す\n- `this` がファイルの場合、ディレクトリを選択すると、ディレクトリ内へファイルを移動させます\n- `this` がファイルの場合、ファイルを選択すると、ディレクトリの移動かつファイル名を変更します\n- `this` がディレクトリの場合、指定したディレクトリへファイルを移動させるため、ディレクトリ名の変更は行えません", + "lineNumber": 129, "unknown": [ { "tagName": "@returns", @@ -7158,7 +7158,7 @@ "spread": false, "optional": false, "name": "file_obj", - "description": "" + "description": "移動先のファイル名及びディレクトリ" } ], "return": { @@ -7171,7 +7171,7 @@ } }, { - "__docId__": 199, + "__docId__": 200, "kind": "method", "name": "renameTo", "memberof": "src/senko/SFile.js~SFile", @@ -7180,8 +7180,8 @@ "static": false, "longname": "src/senko/SFile.js~SFile#renameTo", "access": "public", - "description": "ファイル名を変更", - "lineNumber": 149, + "description": "ファイル名を変更\n- 変更後の `this` は、変更後のファイルを指す\n- 引数はフルパスを渡した場合でもファイル名のみ使用する", + "lineNumber": 172, "unknown": [ { "tagName": "@returns", @@ -7198,7 +7198,7 @@ "spread": false, "optional": false, "name": "file_obj", - "description": "" + "description": "変更後のファイル名" } ], "return": { @@ -7211,7 +7211,7 @@ } }, { - "__docId__": 201, + "__docId__": 202, "kind": "method", "name": "toString", "memberof": "src/senko/SFile.js~SFile", @@ -7221,7 +7221,7 @@ "longname": "src/senko/SFile.js~SFile#toString", "access": "public", "description": "文字列化", - "lineNumber": 172, + "lineNumber": 206, "unknown": [ { "tagName": "@returns", @@ -7239,7 +7239,7 @@ "params": [] }, { - "__docId__": 202, + "__docId__": 203, "kind": "method", "name": "getName", "memberof": "src/senko/SFile.js~SFile", @@ -7249,7 +7249,7 @@ "longname": "src/senko/SFile.js~SFile#getName", "access": "public", "description": "名前を取得", - "lineNumber": 180, + "lineNumber": 214, "unknown": [ { "tagName": "@returns", @@ -7267,7 +7267,7 @@ "params": [] }, { - "__docId__": 203, + "__docId__": 204, "kind": "method", "name": "getParent", "memberof": "src/senko/SFile.js~SFile", @@ -7276,8 +7276,8 @@ "static": false, "longname": "src/senko/SFile.js~SFile#getParent", "access": "public", - "description": "親フォルダの絶対パス\nURLなら最後にスラッシュをつけて返す", - "lineNumber": 199, + "description": "親フォルダの絶対パス\n- 通常のフォルダの場合は、最後の「`/`」は除去される\n- URLなら最後にスラッシュをつけて返す", + "lineNumber": 235, "unknown": [ { "tagName": "@returns", @@ -7295,7 +7295,7 @@ "params": [] }, { - "__docId__": 204, + "__docId__": 205, "kind": "method", "name": "getParentFile", "memberof": "src/senko/SFile.js~SFile", @@ -7305,7 +7305,7 @@ "longname": "src/senko/SFile.js~SFile#getParentFile", "access": "public", "description": "親フォルダ", - "lineNumber": 226, + "lineNumber": 262, "unknown": [ { "tagName": "@returns", @@ -7323,7 +7323,7 @@ "params": [] }, { - "__docId__": 205, + "__docId__": 206, "kind": "method", "name": "getExtensionName", "memberof": "src/senko/SFile.js~SFile", @@ -7333,7 +7333,7 @@ "longname": "src/senko/SFile.js~SFile#getExtensionName", "access": "public", "description": "拡張子(ドットを含まない)", - "lineNumber": 234, + "lineNumber": 270, "unknown": [ { "tagName": "@returns", @@ -7351,7 +7351,7 @@ "params": [] }, { - "__docId__": 206, + "__docId__": 207, "kind": "method", "name": "isAbsolute", "memberof": "src/senko/SFile.js~SFile", @@ -7361,7 +7361,7 @@ "longname": "src/senko/SFile.js~SFile#isAbsolute", "access": "public", "description": "絶対パスかどうか", - "lineNumber": 248, + "lineNumber": 284, "unknown": [ { "tagName": "@returns", @@ -7379,7 +7379,7 @@ "params": [] }, { - "__docId__": 207, + "__docId__": 208, "kind": "method", "name": "isDirectory", "memberof": "src/senko/SFile.js~SFile", @@ -7389,7 +7389,7 @@ "longname": "src/senko/SFile.js~SFile#isDirectory", "access": "public", "description": "フォルダかどうか", - "lineNumber": 262, + "lineNumber": 298, "unknown": [ { "tagName": "@returns", @@ -7407,7 +7407,7 @@ "params": [] }, { - "__docId__": 208, + "__docId__": 209, "kind": "method", "name": "isFile", "memberof": "src/senko/SFile.js~SFile", @@ -7417,7 +7417,7 @@ "longname": "src/senko/SFile.js~SFile#isFile", "access": "public", "description": "ファイルかどうか", - "lineNumber": 276, + "lineNumber": 312, "unknown": [ { "tagName": "@returns", @@ -7435,7 +7435,7 @@ "params": [] }, { - "__docId__": 209, + "__docId__": 210, "kind": "method", "name": "isReadOnly", "memberof": "src/senko/SFile.js~SFile", @@ -7445,7 +7445,7 @@ "longname": "src/senko/SFile.js~SFile#isReadOnly", "access": "public", "description": "読み取り専用ファイルかどうか", - "lineNumber": 290, + "lineNumber": 326, "unknown": [ { "tagName": "@returns", @@ -7463,7 +7463,7 @@ "params": [] }, { - "__docId__": 210, + "__docId__": 211, "kind": "method", "name": "setReadOnly", "memberof": "src/senko/SFile.js~SFile", @@ -7473,7 +7473,7 @@ "longname": "src/senko/SFile.js~SFile#setReadOnly", "access": "public", "description": "読み取り専用ファイルかどうかを設定する", - "lineNumber": 308, + "lineNumber": 344, "unknown": [ { "tagName": "@returns", @@ -7514,7 +7514,7 @@ } }, { - "__docId__": 211, + "__docId__": 212, "kind": "method", "name": "isHidden", "memberof": "src/senko/SFile.js~SFile", @@ -7524,7 +7524,7 @@ "longname": "src/senko/SFile.js~SFile#isHidden", "access": "public", "description": "隠しファイルかどうか", - "lineNumber": 348, + "lineNumber": 384, "unknown": [ { "tagName": "@returns", @@ -7542,7 +7542,7 @@ "params": [] }, { - "__docId__": 212, + "__docId__": 213, "kind": "method", "name": "setHidden", "memberof": "src/senko/SFile.js~SFile", @@ -7552,7 +7552,7 @@ "longname": "src/senko/SFile.js~SFile#setHidden", "access": "public", "description": "隠しファイルかどうかを設定する", - "lineNumber": 366, + "lineNumber": 402, "unknown": [ { "tagName": "@returns", @@ -7593,7 +7593,7 @@ } }, { - "__docId__": 213, + "__docId__": 214, "kind": "method", "name": "lastModified", "memberof": "src/senko/SFile.js~SFile", @@ -7603,7 +7603,7 @@ "longname": "src/senko/SFile.js~SFile#lastModified", "access": "public", "description": "更新日を取得", - "lineNumber": 406, + "lineNumber": 442, "unknown": [ { "tagName": "@returns", @@ -7621,7 +7621,7 @@ "params": [] }, { - "__docId__": 214, + "__docId__": 215, "kind": "method", "name": "setLastModified", "memberof": "src/senko/SFile.js~SFile", @@ -7631,7 +7631,7 @@ "longname": "src/senko/SFile.js~SFile#setLastModified", "access": "public", "description": "更新日を設定(ファイルのみ対応)", - "lineNumber": 423, + "lineNumber": 459, "unknown": [ { "tagName": "@returns", @@ -7660,7 +7660,7 @@ } }, { - "__docId__": 215, + "__docId__": 216, "kind": "method", "name": "length", "memberof": "src/senko/SFile.js~SFile", @@ -7670,7 +7670,7 @@ "longname": "src/senko/SFile.js~SFile#length", "access": "public", "description": "ファイルサイズ", - "lineNumber": 448, + "lineNumber": 484, "unknown": [ { "tagName": "@returns", @@ -7688,7 +7688,7 @@ "params": [] }, { - "__docId__": 216, + "__docId__": 217, "kind": "method", "name": "getFiles", "memberof": "src/senko/SFile.js~SFile", @@ -7698,7 +7698,7 @@ "longname": "src/senko/SFile.js~SFile#getFiles", "access": "public", "description": "配下のファイル名の一覧を取得", - "lineNumber": 463, + "lineNumber": 499, "unknown": [ { "tagName": "@returns", @@ -7716,7 +7716,7 @@ "params": [] }, { - "__docId__": 217, + "__docId__": 218, "kind": "method", "name": "getSubFolders", "memberof": "src/senko/SFile.js~SFile", @@ -7726,7 +7726,7 @@ "longname": "src/senko/SFile.js~SFile#getSubFolders", "access": "public", "description": "配下のサブフォルダ名の一覧を取得", - "lineNumber": 482, + "lineNumber": 518, "unknown": [ { "tagName": "@returns", @@ -7744,7 +7744,7 @@ "params": [] }, { - "__docId__": 218, + "__docId__": 219, "kind": "method", "name": "getNormalizedPathName", "memberof": "src/senko/SFile.js~SFile", @@ -7754,7 +7754,7 @@ "longname": "src/senko/SFile.js~SFile#getNormalizedPathName", "access": "public", "description": "区切り文字と終端を正規化した文字列を取得", - "lineNumber": 501, + "lineNumber": 537, "unknown": [ { "tagName": "@returns", @@ -7772,7 +7772,7 @@ "params": [] }, { - "__docId__": 219, + "__docId__": 220, "kind": "method", "name": "list", "memberof": "src/senko/SFile.js~SFile", @@ -7782,7 +7782,7 @@ "longname": "src/senko/SFile.js~SFile#list", "access": "public", "description": "配下のファイル名とフォルダ名を取得", - "lineNumber": 516, + "lineNumber": 552, "unknown": [ { "tagName": "@returns", @@ -7800,7 +7800,7 @@ "params": [] }, { - "__docId__": 220, + "__docId__": 221, "kind": "method", "name": "getAbsolutePath", "memberof": "src/senko/SFile.js~SFile", @@ -7810,7 +7810,7 @@ "longname": "src/senko/SFile.js~SFile#getAbsolutePath", "access": "public", "description": "絶対パスを取得", - "lineNumber": 539, + "lineNumber": 575, "unknown": [ { "tagName": "@returns", @@ -7828,7 +7828,7 @@ "params": [] }, { - "__docId__": 221, + "__docId__": 222, "kind": "method", "name": "mkdir", "memberof": "src/senko/SFile.js~SFile", @@ -7838,7 +7838,7 @@ "longname": "src/senko/SFile.js~SFile#mkdir", "access": "public", "description": "フォルダを作成\n- フォルダは1つのみ指定可能\n- すでにフォルダがある場合はエラーを返す。", - "lineNumber": 584, + "lineNumber": 620, "unknown": [ { "tagName": "@returns", @@ -7856,7 +7856,7 @@ "params": [] }, { - "__docId__": 222, + "__docId__": 223, "kind": "method", "name": "mkdirs", "memberof": "src/senko/SFile.js~SFile", @@ -7866,7 +7866,7 @@ "longname": "src/senko/SFile.js~SFile#mkdirs", "access": "public", "description": "フォルダを作成\n- 作成したいフォルダを続けて記載が可能\n- フォルダがない場合はフォルダを作成していく", - "lineNumber": 616, + "lineNumber": 652, "unknown": [ { "tagName": "@returns", @@ -7884,7 +7884,7 @@ "params": [] }, { - "__docId__": 223, + "__docId__": 224, "kind": "method", "name": "run", "memberof": "src/senko/SFile.js~SFile", @@ -7894,7 +7894,7 @@ "longname": "src/senko/SFile.js~SFile#run", "access": "public", "description": "実行ファイルを起動する", - "lineNumber": 638, + "lineNumber": 674, "unknown": [ { "tagName": "@returns", @@ -7937,7 +7937,7 @@ } }, { - "__docId__": 224, + "__docId__": 225, "kind": "method", "name": "writeLine", "memberof": "src/senko/SFile.js~SFile", @@ -7947,7 +7947,7 @@ "longname": "src/senko/SFile.js~SFile#writeLine", "access": "public", "description": "1行書き加える", - "lineNumber": 655, + "lineNumber": 691, "unknown": [ { "tagName": "@returns", @@ -7976,7 +7976,7 @@ } }, { - "__docId__": 225, + "__docId__": 226, "kind": "method", "name": "getTextFile", "memberof": "src/senko/SFile.js~SFile", @@ -7986,7 +7986,7 @@ "longname": "src/senko/SFile.js~SFile#getTextFile", "access": "public", "description": "ローカル、インターネット上のファイルをテキストとして開く\n- 改行コードは `\\n` に統一されます", - "lineNumber": 682, + "lineNumber": 718, "unknown": [ { "tagName": "@returns", @@ -8017,7 +8017,7 @@ } }, { - "__docId__": 226, + "__docId__": 227, "kind": "method", "name": "setTextFile", "memberof": "src/senko/SFile.js~SFile", @@ -8027,7 +8027,7 @@ "longname": "src/senko/SFile.js~SFile#setTextFile", "access": "public", "description": "テキストファイルを保存", - "lineNumber": 821, + "lineNumber": 857, "unknown": [ { "tagName": "@returns", @@ -8092,7 +8092,7 @@ } }, { - "__docId__": 227, + "__docId__": 228, "kind": "method", "name": "getBinaryFile", "memberof": "src/senko/SFile.js~SFile", @@ -8102,7 +8102,7 @@ "longname": "src/senko/SFile.js~SFile#getBinaryFile", "access": "public", "description": "ローカル、インターネット上のファイルをバイナリとして開く\n- 参考速度:0.5 sec/MB\n- 巨大なファイルの一部を調べる場合は、位置とサイズを指定した方がよい", - "lineNumber": 904, + "lineNumber": 940, "unknown": [ { "tagName": "@returns", @@ -8141,7 +8141,7 @@ } }, { - "__docId__": 228, + "__docId__": 229, "kind": "method", "name": "setBinaryFile", "memberof": "src/senko/SFile.js~SFile", @@ -8151,7 +8151,7 @@ "longname": "src/senko/SFile.js~SFile#setBinaryFile", "access": "public", "description": "バイナリファイルを保存\n- 参考速度:1.0 sec/MB", - "lineNumber": 1037, + "lineNumber": 1073, "unknown": [ { "tagName": "@returns", @@ -8190,7 +8190,7 @@ } }, { - "__docId__": 229, + "__docId__": 230, "kind": "method", "name": "getHashCode", "memberof": "src/senko/SFile.js~SFile", @@ -8200,7 +8200,7 @@ "longname": "src/senko/SFile.js~SFile#getHashCode", "access": "public", "description": "ファイルのハッシュ値を計算する", - "lineNumber": 1112, + "lineNumber": 1148, "unknown": [ { "tagName": "@returns", @@ -8231,7 +8231,7 @@ } }, { - "__docId__": 230, + "__docId__": 231, "kind": "method", "name": "createTempFile", "memberof": "src/senko/SFile.js~SFile", @@ -8241,7 +8241,7 @@ "longname": "src/senko/SFile.js~SFile.createTempFile", "access": "public", "description": "テンポラリフォルダ内の適当なファイル名を取得", - "lineNumber": 1144, + "lineNumber": 1180, "unknown": [ { "tagName": "@returns", @@ -8259,7 +8259,7 @@ "params": [] }, { - "__docId__": 231, + "__docId__": 232, "kind": "method", "name": "getCurrentDirectory", "memberof": "src/senko/SFile.js~SFile", @@ -8269,7 +8269,7 @@ "longname": "src/senko/SFile.js~SFile.getCurrentDirectory", "access": "public", "description": "カレントディレクトリを取得", - "lineNumber": 1155, + "lineNumber": 1191, "unknown": [ { "tagName": "@returns", @@ -8287,7 +8287,7 @@ "params": [] }, { - "__docId__": 232, + "__docId__": 233, "kind": "method", "name": "setCurrentDirectory", "memberof": "src/senko/SFile.js~SFile", @@ -8297,7 +8297,7 @@ "longname": "src/senko/SFile.js~SFile.setCurrentDirectory", "access": "public", "description": "カレントディレクトリを設定", - "lineNumber": 1164, + "lineNumber": 1200, "params": [ { "nullable": null, @@ -8314,7 +8314,7 @@ "return": null }, { - "__docId__": 233, + "__docId__": 234, "kind": "method", "name": "each", "memberof": "src/senko/SFile.js~SFile", @@ -8324,7 +8324,7 @@ "longname": "src/senko/SFile.js~SFile#each", "access": "public", "description": "フォルダの中のフォルダとファイルに対して指定した関数を実行する", - "lineNumber": 1176, + "lineNumber": 1212, "unknown": [ { "tagName": "@returns", @@ -8353,7 +8353,7 @@ } }, { - "__docId__": 234, + "__docId__": 235, "kind": "method", "name": "getAllFiles", "memberof": "src/senko/SFile.js~SFile", @@ -8363,7 +8363,7 @@ "longname": "src/senko/SFile.js~SFile#getAllFiles", "access": "public", "description": "サブフォルダの中まで探索して全てのファイルとフォルダを取得", - "lineNumber": 1252, + "lineNumber": 1288, "unknown": [ { "tagName": "@returns", @@ -8381,7 +8381,7 @@ "params": [] }, { - "__docId__": 235, + "__docId__": 236, "kind": "method", "name": "searchFile", "memberof": "src/senko/SFile.js~SFile", @@ -8390,12 +8390,12 @@ "static": false, "longname": "src/senko/SFile.js~SFile#searchFile", "access": "public", - "description": "指定した条件にあうファイルを探す\n関数を指定する場合は、ファイル名とフルパスが引数に渡されます", - "lineNumber": 1274, + "description": "指定した条件にあうファイルを探す\n- 関数を指定する場合は、ファイル名とフルパスが引数に渡されます", + "lineNumber": 1312, "unknown": [ { "tagName": "@returns", - "tagValue": "{SFile|null}" + "tagValue": "{SFile|SFile[]|null}" } ], "params": [ @@ -8404,18 +8404,32 @@ "types": [ "string", "SFile", - "function(string, string): boolean" + "RegExp", + "function(SFile): boolean" ], "spread": false, "optional": false, "name": "file_obj", "description": "" + }, + { + "nullable": null, + "types": [ + "boolean" + ], + "spread": false, + "optional": true, + "defaultValue": "false", + "defaultRaw": false, + "name": "is_all_file", + "description": "trueで指定した場合は条件に合うファイルを複数見つけて配列で返す" } ], "return": { "nullable": null, "types": [ "SFile", + "SFile[]", "null" ], "spread": false, @@ -8423,7 +8437,7 @@ } }, { - "__docId__": 236, + "__docId__": 237, "kind": "method", "name": "compress", "memberof": "src/senko/SFile.js~SFile", @@ -8433,7 +8447,7 @@ "longname": "src/senko/SFile.js~SFile.compress", "access": "public", "description": "圧縮する\n- 圧縮後のファイル名の拡張子で圧縮したい形式を指定する\n- Windows標準の機能を使用して圧縮する( `zip` のみ対応)\n- 外部ツール `7-Zip` がインストール/設定されている場合は、それを利用して圧縮する", - "lineNumber": 1315, + "lineNumber": 1387, "unknown": [ { "tagName": "@returns", @@ -8476,7 +8490,7 @@ } }, { - "__docId__": 237, + "__docId__": 238, "kind": "method", "name": "extract", "memberof": "src/senko/SFile.js~SFile", @@ -8486,7 +8500,7 @@ "longname": "src/senko/SFile.js~SFile.extract", "access": "public", "description": "展開する\n- Windows標準の機能を使用して展開する( `zip` のみ対応)\n- 外部ツール `7-Zip` がインストール/設定されている場合は、それを利用して展開する", - "lineNumber": 1416, + "lineNumber": 1488, "unknown": [ { "tagName": "@returns", @@ -8527,7 +8541,7 @@ } }, { - "__docId__": 238, + "__docId__": 239, "kind": "method", "name": "setCompressTool", "memberof": "src/senko/SFile.js~SFile", @@ -8537,7 +8551,7 @@ "longname": "src/senko/SFile.js~SFile.setCompressTool", "access": "public", "description": "圧縮/展開用のツールを設定する\n- このツールを利用して `compress`, `extract` が実行されます\n- 未設定/未インストールの場合は、Windows標準の機能のみを利用し、`zip`のみ対応します\n- `7-zip` のコマンドライン版 (`7za.exe`)のみ対応", - "lineNumber": 1487, + "lineNumber": 1558, "unknown": [ { "tagName": "@returns", @@ -8567,7 +8581,7 @@ } }, { - "__docId__": 239, + "__docId__": 240, "kind": "method", "name": "getCompressTool", "memberof": "src/senko/SFile.js~SFile", @@ -8577,7 +8591,7 @@ "longname": "src/senko/SFile.js~SFile.getCompressTool", "access": "public", "description": "圧縮/展開用のツールを取得する\n- このツールを利用して `compress`, `extract` が実行されます\n- 未設定/未インストールの場合は、Windows標準の機能のみを利用し、`zip`のみ対応します\n- 取得できない場合は `null` を返します", - "lineNumber": 1503, + "lineNumber": 1574, "unknown": [ { "tagName": "@returns", @@ -8596,10 +8610,10 @@ "params": [] }, { - "__docId__": 240, + "__docId__": 241, "kind": "file", "name": "src/senko/System.js", - "content": "/**\n * The script is part of SenkoWSH.\n * \n * AUTHOR:\n * natade (http://twitter.com/natadea)\n * \n * LICENSE:\n * The MIT license https://opensource.org/licenses/MIT\n */\n\nimport Polyfill from \"./polyfill/Polyfill.js\";\nimport SFile from \"./SFile.js\";\nimport Format from \"./Format.js\";\n\n/**\n * @type {boolean}\n * @private\n */\nconst is_wscript = /wscript\\.exe$/i.test(WSH.FullName);\n\n/**\n * @type {boolean}\n * @private\n */\nconst is_cscript = /cscript\\.exe$/i.test(WSH.FullName);\n\n/**\n * 文字列へ変換します。\n * @param {any} data \n * @private\n */\nconst toString = function(data) {\n\tif(data === null) {\n\t\treturn \"[null]\";\n\t}\n\telse if(data === undefined) {\n\t\treturn \"[undefined]\";\n\t}\n\tconst string_data = data.toString();\n\tif(string_data === \"[object Error]\") {\n\t\tconst e = data;\n\t\tconst error_name\t= e.name ? e.name : \"Error\";\n\t\tconst error_number\t= e.number ? Format.textf(\"0x%08X\", e.number) : \"0x00000000\";\n\t\tconst error_message\t= e.message ? e.message : \"エラーが発生しました。\";\n\t\treturn Format.textf(\"%s(%s) %s\", error_name, error_number, error_message);\n\t}\n\treturn string_data;\n};\n\n\n/**\n * 実行結果\n * @typedef {Object} SystemExecResult\n * @property {string} out\n * @property {string} error\n * @property {number} exit_code\n */\n\n/**\n * システム用のクラス\n * - 文字列の入出力\n * - スリープ、停止\n * - GUIモード、CUIモードの切り替え\n * - バッチファイルへの引数の情報\n * - カレントディレクトリ情報\n */\nexport default class System {\n\n\t/**\n\t * 文字列を表示(最終行で自動で改行されない)\n\t * @param {any} text\n\t */\n\tstatic print(text) {\n\t\tconst output = toString(text);\n\t\tif(is_cscript) {\n\t\t\tWSH.StdOut.Write(output);\n\t\t}\n\t\telse {\n\t\t\tWScript.Echo(output);\n\t\t}\n\t}\n\n\t/**\n\t * 文字列を表示(最終行で自動で改行される)\n\t * @param {any} text\n\t */\n\tstatic println(text) {\n\t\tconst output = toString(text);\n\t\tif(is_cscript) {\n\t\t\tSystem.print(output + \"\\n\");\n\t\t}\n\t\telse {\n\t\t\tSystem.print(output);\n\t\t}\n\t}\n\n\t/**\n\t * 指定したフォーマットで整形した文字列を表示\n\t * @param {any} text \n\t * @param {...any} parm パラメータは可変引数\n\t */\n\tstatic printf() {\n\t\tconst x = [];\n\t\tfor(let i = 0 ; i < arguments.length ; i++) {\n\t\t\tx[i] = arguments[i];\n\t\t\tif(i === 0) {\n\t\t\t\tx[i] = toString(x[i]);\n\t\t\t}\n\t\t}\n\t\tSystem.println(Format.textf.apply(this, x));\n\t}\n\n\t/**\n\t * キーボードのテキスト入力を取得\n\t * @returns {string}\n\t */\n\tstatic readLine() {\n\t\treturn WScript.StdIn.ReadLine();\n\t}\n\t\n\t/**\n\t * UNIX時間をミリ秒で取得\n\t * @returns {number}\n\t */\n\tstatic currentTimeMillis() {\n\t\tconst date = new Date();\n\t\treturn date.getTime();\n\t}\n\n\t/**\n\t * 処理を一時停止\n\t * @param {number} time_sec 停止する秒数\n\t */\n\tstatic sleep(time_sec) {\n\t\tWScript.Sleep((time_sec * 1000) | 0);\n\t}\n\t\n\t/**\n\t * 処理を停止\n\t */\n\tstatic stop() {\n\t\twhile(true) {\n\t\t\tWScript.Sleep(1000);\n\t\t}\n\t}\n\t\n\t/**\n\t * ビープ音を鳴らす\n\t * @param {number} frequency_hz - 周波数\n\t * @param {number} time_sec - 鳴らす秒数\n\t */\n\tstatic beep(frequency_hz, time_sec) {\n\t\tSystem.WindowsAPI(\n\t\t\t\"kernel32.dll\",\n\t\t\t\"bool Beep(uint dwFreq, uint dwDuration)\",\n\t\t\t\"$api::Beep(\" + (frequency_hz | 0) + \", \" + ((time_sec * 1000) | 0) + \");\"\n\t\t);\n\t}\n\n\t/**\n\t * 指定したコマンドを別プロセスとして実行する\n\t * @param {string} command - コマンド\n\t * @param {number} [style=1] - 起動オプション\n\t * @param {boolean} [is_wait=false] - プロセスが終了するまで待つ\n\t */\n\tstatic run(command, style, is_wait) {\n\t\tconst NormalFocus = 1;\n\t\tconst intWindowStyle = style !== undefined ? style : NormalFocus;\n\t\tconst bWaitOnReturn = is_wait !== undefined ? is_wait : false;\n\t\tconst shell = WScript.CreateObject(\"WScript.Shell\");\n\t\t// @ts-ignore\n\t\treturn shell.Run(command, intWindowStyle, bWaitOnReturn);\n\t}\n\n\t/**\n\t * 指定したコマンドを子プロセスとして実行する\n\t * @param {string} command \n\t * @returns {SystemExecResult}\n\t */\n\tstatic exec(command) {\n\t\tconst shell = WScript.CreateObject(\"WScript.Shell\");\n\t\tconst exec = shell.Exec(command);\n\t\tconst stdin = exec.StdIn;\n\t\tconst stdout = exec.StdOut;\n\t\tconst stderr = exec.StdErr;\n\t\twhile(exec.Status === 0) {\n\t\t\tWScript.Sleep(10);\n\t\t}\n\t\tconst exit_code = exec.ExitCode;\n\t\tstdin.Close();\n\t\t// @ts-ignore\n\t\tconst out = stdout.ReadAll().replace(/\\r?\\n$/, \"\");\n\t\tstdout.Close();\n\t\t// @ts-ignore\n\t\tconst error = stderr.ReadAll().replace(/\\r?\\n$/, \"\");\n\t\tstderr.Close();\n\t\treturn {\n\t\t\texit_code : exit_code,\n\t\t\tout : out,\n\t\t\terror : error\n\t\t};\n\t}\n\t\n\t/**\n\t * 指定した変数が定義されているか調べる\n\t * @param {string} variable_name\n\t * @returns {boolean}\n\t */\n\t static isDefined(variable_name) {\n\t\treturn variable_name in globalThis;\n\t}\n\t\n\t/**\n\t * プログラムを終了させます。\n\t * @param {number} [exit_code=0] \n\t */\n\tstatic exit(exit_code) {\n\t\tWScript.Quit(exit_code ? exit_code : 0);\n\t}\n\t\n\t/**\n\t * CUIで起動しなおす\n\t * @param {boolean} [is_use_chakra] - 高速なChakraエンジンを利用する(wsfが開けなくなる)\n\t */\n\tstatic executeOnCScript(is_use_chakra) {\n\t\tconst iis_use_chakra = is_use_chakra !== undefined ? is_use_chakra : false;\n\t\tif(is_wscript) {\n\t\t\t// CScript で起動しなおす\n\t\t\tconst code = [];\n\t\t\tconst args = System.getArguments();\n\t\t\tcode.push(\"\\\"C:\\\\Windows\\\\System32\\\\cscript.exe\\\"\");\n\t\t\tcode.push(\"//NoLogo\");\n\t\t\tif(iis_use_chakra) {\n\t\t\t\tcode.push(\"//E:{16d51579-a30b-4c8b-a276-0ff4dc41e755}\");\n\t\t\t}\n\t\t\tcode.push(\"\\\"\" + WScript.ScriptFullName + \"\\\"\");\n\t\t\tfor(let i = 0; i < args.length; i++) {\n\t\t\t\tcode.push(\"\\\"\" + args[i] + \"\\\"\");\n\t\t\t}\n\t\t\tSystem.run(code.join(\" \"));\n\t\t\tSystem.exit();\n\t\t}\n\t}\n\t\n\t/**\n\t * GUIで起動しなおす\n\t */\n\tstatic executeOnWScript() {\n\t\t// cscriptで起動しているか\n\t\tif(is_cscript) {\n\t\t\t// WScript で起動しなおす\n\t\t\tconst code = [];\n\t\t\tconst args = System.getArguments();\n\t\t\tcode.push(\"\\\"C:\\\\Windows\\\\System32\\\\wscript.exe\\\"\");\n\t\t\tcode.push(\"\\\"\" + WScript.ScriptFullName + \"\\\"\");\n\t\t\tfor(let i = 0; i < args.length; i++) {\n\t\t\t\tcode.push(\"\\\"\" + args[i] + \"\\\"\");\n\t\t\t}\n\t\t\tSystem.run(code.join(\" \"));\n\t\t\tSystem.exit();\n\t\t}\n\t}\n\t\n\t/**\n\t * 指定した環境変数の値を取得する\n\t * @param {string} env_name 環境変数(%は省略可能)\n\t * @returns {string}\n\t */\n\t static getEnvironmentString(env_name) {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\tconst env_param = \"%\" + env_name.replace(/%/g, \"\") + \"%\";\n\t\tconst env_value = shell.ExpandEnvironmentStrings(env_param);\n\t\treturn env_param === env_value ? \"\" : env_value;\n\t}\n\n\t/**\n\t * スクリプトファイルへの引数を取得\n\t * @returns {string[]}\n\t */\n\tstatic getArguments() {\n\t\tconst args = [];\n\t\tfor(let i = 0; i < WScript.Arguments.length; i++) {\n\t\t\targs[i] = WScript.Arguments(i);\n\t\t}\n\t\treturn args;\n\t}\n\n\t/**\n\t * カレントディレクトリを設定\n\t * @param {string} filename\n\t */\n\tstatic setCurrentDirectory(filename) {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\tshell.CurrentDirectory = filename.toString();\n\t}\n\t\n\t/**\n\t * カレントディレクトリを取得\n\t * @returns {string}\n\t */\n\tstatic getCurrentDirectory() {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\treturn shell.CurrentDirectory;\n\t}\n\n\t/**\n\t * 実行中のスクリプトがあるカレントディレクトリを取得\n\t * @returns {string}\n\t */\n\tstatic getScriptDirectory() {\n\t\tconst x = WSH.ScriptFullName.match(/.*\\\\/)[0];\n\t\treturn(x.substring(0 ,x.length - 1));\n\t}\n\t\n\t/**\n\t * 実行中のスクリプトがあるディレクトリをカレントディレクトリに設定\n\t */\n\tstatic initializeCurrentDirectory() {\n\t\tconst shell = WScript.CreateObject(\"WScript.Shell\");\n\t\tshell.CurrentDirectory = System.getScriptDirectory();\n\t}\n\n\t/**\n\t * BatchScript を実行する\n\t * \n\t * @param {string} source\n\t * @param {string} [charset=\"ansi\"] - 文字コード\n\t * @returns {SystemExecResult|null}\n\t */\n\tstatic BatchScript(source, charset) {\n\t\tconst icharset = charset !== undefined ? charset.toLowerCase() : \"ansi\";\n\t\tconst is_ansi = /shift_jis|sjis|ascii|ansi/i.test(icharset);\n\t\tconst is_utf16 = /unicode|utf-16le/i.test(icharset);\n\t\tconst is_line = !/\\n/.test(source);\n\n\t\t// 改行がない場合はコマンドモードで実行する\n\t\tif(is_line) {\n\t\t\t// コマンドモードで実行する\n\t\t\tconst cmd_base = is_utf16 ? \"cmd /u /d /c\" : \"cmd /d /c\";\n\t\t\t// コマンドモードで実行するため、特定の文字をエスケープさせる\n\t\t\tconst command = cmd_base + \" \" + source;\n\t\t\tconst exec = System.exec(command);\n\t\t\treturn exec;\n\t\t}\n\t\telse {\n\t\t\tconst file = new SFile(SFile.createTempFile().getAbsolutePath() + \".bat\");\n\t\t\tlet cs;\n\t\t\tcs = is_ansi ? \"shift_jis\" : \"\";\n\t\t\tcs = is_utf16 ? \"shift_jis\" : cs;\n\t\t\tcs = cs === \"\" ? icharset : cs;\n\t\t\tconst ret = file.setTextFile(source, cs, \"\\r\\n\");\n\t\t\tif(ret === false) {\n\t\t\t\tconsole.log(cs);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst cmd_base = is_utf16 ? \"cmd /u /d /c\" : \"cmd /d /c\";\n\t\t\tconst command = cmd_base + \" \\\"\" + file + \"\\\"\";\n\t\t\tconst exec = System.exec(command);\n\t\t\tfile.remove();\n\t\t\treturn exec;\n\t\t}\n\t}\n\n\t/**\n\t * PowerShell を実行する\n\t * \n\t * @param {string} source\n\t * @returns {string}\n\t */\n\tstatic PowerShell(source) {\n\t\t// 改行がない場合はコマンドモードで実行する\n\t\tif(!/\\n/.test(source)) {\n\t\t\t// スレッドセーフモードでコマンドモードで実行する\n\t\t\tconst powershell_base = \"powershell -sta -Command\";\n\t\t\t// コマンドモードで実行するため、特定の文字をエスケープさせる\n\t\t\tconst command = (powershell_base + \" \" + source).replace(/([\\\\\"])/g, \"\\\\$1\");\n\t\t\tconst exec = System.exec(command);\n\t\t\tif(exec.exit_code !== 0) {\n\t\t\t\tconsole.log(exec.exit_code);\n\t\t\t}\n\t\t\t// 最終行を除去してなるべく1行で返す\n\t\t\treturn exec.out.replace(/\\r?\\n$/, \"\");\n\t\t}\n\t\telse {\n\t\t\tconst file = new SFile(SFile.createTempFile().getAbsolutePath() + \".ps1\");\n\t\t\tfile.setTextFile(source, \"utf-16le\", \"\\r\\n\");\n\t\t\t// 本システムでスクリプトの実行が無効になっている可能性があるため一時的に実行ポリシーを変更して実行する\n\t\t\t// ※変更しないと「ParentContainsErrorRecordException」が発生する場合がある\n\t\t\tconst powershell_base = \"powershell -NoProfile -ExecutionPolicy Unrestricted\";\n\t\t\tconst command = powershell_base + \" \\\"\" + file + \"\\\"\";\n\t\t\tconst exec = System.exec(command);\n\t\t\tfile.remove();\n\t\t\tif(exec.exit_code !== 0) {\n\t\t\t\tconsole.log(exec.exit_code);\n\t\t\t}\n\t\t\treturn exec.out;\n\t\t}\n\t}\n\n\t/**\n\t * WindowsAPI を実行する\n\t * \n\t * 例\n\t * - `dll_name` : `\"user32.dll\"`\n\t * - `function_text` : `\"int MessageBox(IntPtr hWnd, string lpText, string lpCaption, UInt32 uType)\"\"`\n\t * - `exec_text` : `\"$api::MessageBox(0, \\\"テキスト\\\", \\\"キャプション\\\", 0);\"`\n\t * @param {string} dll_name - 利用するdll\n\t * @param {string} function_text - 関数の定義データ(`$api`に代入されます。)\n\t * @param {string} exec_text - 実行コマンド\n\t * @returns {string}\n\t */\n\tstatic WindowsAPI(dll_name, function_text, exec_text) {\n\t\t// 利用例\n\t\t// System.WindowsAPI(\n\t\t// \t\"user32.dll\",\n\t\t// \t\"int MessageBox(IntPtr hWnd, string lpText, string lpCaption, UInt32 uType)\",\n\t\t// \t\"$api::MessageBox(0, \\\"テキスト\\\", \\\"キャプション\\\", 0);\"\n\t\t// );\n\t\t//\n\n\t\t/*\n\t\t\tPowerShell 2.0 の Add-Type を使用している\n\t\t\t$api = Add-Type -Name \"api\" -MemberDefinition '\n\t\t\t\t[DllImport(\"user32.dll\")] public extern static int MessageBox(IntPtr hWnd, string lpText, string lpCaption, UInt32 uType);\n\t\t\t' -PassThru;\n\t\t\t$api::MessageBox(0, \\\"テキスト\\\", \\\"キャプション\\\", 0);\n\t\t*/\n\n\t\t// ダブルクォーテーションだとエスケープが面倒なので、ここはシングルクォーテーションを使用する\n\t\t// eslint-disable-next-line quotes\n\t\tconst api_base = `$api = Add-Type -Name \"api\" -MemberDefinition \"[DllImport(\"\"` + dll_name + `\"\")] public extern static ` + function_text + `;\" -PassThru;`;\n\t\tconst command = api_base + \" \" + exec_text;\n\t\treturn System.PowerShell(command);\n\t}\n\n\t/**\n\t * クリップボードからテキストを取得する\n\t * @returns {string}\n\t */\n\tstatic getClipBoardText() {\n\t\t/*\n\t\t\tAdd-Type -Assembly System.Windows.Forms;\n\t\t\t[System.Windows.Forms.Clipboard]::GetText();\n\t\t*/\n\t\tconst command = \"Add-Type -Assembly System.Windows.Forms; [System.Windows.Forms.Clipboard]::GetText();\";\n\t\treturn System.PowerShell(command);\n\t}\n\n\t/**\n\t * クリップボードへテキストを設定する\n\t * @param {string} text\n\t */\n\tstatic setClipBoardText(text) {\n\t\t/*\n\t\t\tAdd-Type -Assembly System.Windows.Forms;\n\t\t\t[System.Windows.Forms.Clipboard]::SetText(\\\"\" + text + \"\\\", 1);\n\t\t*/\n\t\tconst command = \"Add-Type -Assembly System.Windows.Forms; [System.Windows.Forms.Clipboard]::SetText(\\\"\" + text + \"\\\", 1);\";\n\t\t// PowerShell 5.0以降\n\t\t// command = \"Set-Clipboard \\\"これでもコピー可能\\\"\";\n\t\tSystem.PowerShell(command);\n\t}\n\n\t/**\n\t * `XMLHttpRequest` を作成\n\t * - 取得できない場合は `null`\n\t * \n\t * @returns {XMLHttpRequest}\n\t */\n\t static createXMLHttpRequest() {\n\t\ttry {\n\t\t\treturn new XMLHttpRequest();\n\t\t}\n\t\tcatch (e) {\n\t\t\tconst MSXMLHTTP = [\n\t\t\t\t\"WinHttp.WinHttpRequest.5.1\",\n\t\t\t\t\"WinHttp.WinHttpRequest.5\",\n\t\t\t\t\"WinHttp.WinHttpRequest\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.6.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.5.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.4.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.3.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP\",\n\t\t\t\t\"Microsoft.ServerXMLHTTP\",\n\t\t\t\t\"Msxml2.XMLHTTP.6.0\",\n\t\t\t\t\"Msxml2.XMLHTTP.5.0\",\n\t\t\t\t\"Msxml2.XMLHTTP.4.0\",\n\t\t\t\t\"Msxml2.XMLHTTP.3.0\",\n\t\t\t\t\"Msxml2.XMLHTTP\",\n\t\t\t\t\"Microsoft.XMLHTTP\"\n\t\t\t];\n\t\t\t// ※ WinHttp.WinHttpRequest は onreadystatechange の書き換えができない\n\t\t\tfor(let i = 0; i < MSXMLHTTP.length; i++) {\n\t\t\t\ttry {\n\t\t\t\t\treturn new ActiveXObject(MSXMLHTTP[i]);\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * `MSXML2.DOMDocument` を作成\n\t * - 取得できない場合は `null`\n\t * \n\t * @returns {any}\n\t */\n\t static createMSXMLDOMDocument() {\n\t\tconst MSXMLDOM = [\n\t\t\t\"Msxml2.DOMDocument.6.0\",\n\t\t\t\"Msxml2.DOMDocument.3.0\",\n\t\t\t\"Msxml2.DOMDocument\",\n\t\t\t\"Microsoft.XMLDOM\"\n\t\t];\n\t\tfor(let i = 0; i < MSXMLDOM.length; i++) {\n\t\t\ttry {\n\t\t\t\treturn new ActiveXObject(MSXMLDOM[i]);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * `Byte 配列` から数値配列を作成する\n\t * - `ADODB.Stream` などを用いて取得したバイナリ配列を `JavaScript` でも扱える型へ変更する\n\t * \n\t * @param {any} byte_array\n\t * @returns {number[]}\n\t */\n\tstatic createNumberArrayFromByteArray(byte_array) {\n\t\tconst dom = System.createMSXMLDOMDocument();\n\t\tif(dom === null) {\n\t\t\tconsole.log(\"createMSXMLDOMDocument\")\n\t\t\treturn [];\n\t\t}\n\n\t\t// バイト配列から16進数テキストへ変換\n\t\t// 参考\n\t\t// https://qiita.com/tnakagawa/items/9bcc26b501f5b995d896\n\t\tconst element = dom.createElement(\"hex\");\n\t\telement.dataType = \"bin.hex\";\n\t\telement.nodeTypedValue = byte_array;\n\t\t/**\n\t\t * @type {string}\n\t\t */\n\t\tconst hex_text = element.text;\n\t\tconst out = new Array(hex_text.length / 2);\n\t\t// バイト文字列から配列へ変更\n\t\tfor(let i = 0; i < out.length; i++) {\n\t\t\tout[i] = Number.parseInt(hex_text.substr(i * 2, 2), 16);\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 数値配列から`Byte 配列`を作成する\n\t * - `ADODB.Stream` などを用いて取得したバイナリ配列を `JavaScript` でも扱える型へ変更する\n\t * - `offset` を指定した場合は、出力したバイト配列はその位置までは `NUL` で埋まった配列となる\n\t * \n\t * @param {number[]} number_array\n\t * @param {number} [offset = 0]\n\t * @returns {any}\n\t */\n\t static createByteArrayFromNumberArray(number_array, offset) {\n\t\tconst dom = System.createMSXMLDOMDocument();\n\t\tif(dom === null) {\n\t\t\tconsole.log(\"createMSXMLDOMDocument\")\n\t\t\treturn null;\n\t\t}\n\t\tlet max_size = offset !== undefined ? offset : 0;\n\t\tlet hex_string = [];\n\t\t// offsetが設定されている場合は、オフセット位置まで00で埋める\n\t\tlet p;\n\t\tfor(p = 0; p < max_size; p++) {\n\t\t\thex_string[p] = \"00\";\n\t\t}\n\t\tmax_size += number_array.length;\n\t\t// 16進数の文字列を作成する\n\t\tfor(let i = 0; p < max_size; i++, p++) {\n\t\t\tif(number_array[i] < 16) {\n\t\t\t\thex_string[p] = \"0\" + number_array[i].toString(16);\n\t\t\t}\n\t\t\telse {\n\t\t\t\thex_string[p] = number_array[i].toString(16);\n\t\t\t}\n\t\t}\n\t\t// バイト配列から16進数テキストへ変換\n\t\t// 参考\n\t\t// https://qiita.com/tnakagawa/items/9bcc26b501f5b995d896\n\t\tconst element = dom.createElement(\"hex\");\n\t\telement.dataType = \"bin.hex\";\n\t\telement.text = hex_string.join(\"\");\n\t\tconst byte_array = element.nodeTypedValue;\n\t\treturn byte_array;\n\t}\n\n}\n\n\n", + "content": "/**\n * The script is part of SenkoWSH.\n * \n * AUTHOR:\n * natade (http://twitter.com/natadea)\n * \n * LICENSE:\n * The MIT license https://opensource.org/licenses/MIT\n */\n\nimport Polyfill from \"./polyfill/Polyfill.js\";\nimport SFile from \"./SFile.js\";\nimport Format from \"./Format.js\";\n\n/**\n * @type {boolean}\n * @private\n */\nconst is_wscript = /wscript\\.exe$/i.test(WSH.FullName);\n\n/**\n * @type {boolean}\n * @private\n */\nconst is_cscript = /cscript\\.exe$/i.test(WSH.FullName);\n\n/**\n * 文字列へ変換します。\n * @param {any} data \n * @private\n */\nconst toString = function(data) {\n\tif(data === null) {\n\t\treturn \"[null]\";\n\t}\n\telse if(data === undefined) {\n\t\treturn \"[undefined]\";\n\t}\n\tconst string_data = data.toString();\n\tif(string_data === \"[object Error]\") {\n\t\tconst e = data;\n\t\tconst error_name\t= e.name ? e.name : \"Error\";\n\t\tconst error_number\t= e.number ? Format.textf(\"0x%08X\", e.number) : \"0x00000000\";\n\t\tconst error_message\t= e.message ? e.message : \"エラーが発生しました。\";\n\t\treturn Format.textf(\"%s(%s) %s\", error_name, error_number, error_message);\n\t}\n\treturn string_data;\n};\n\n\n/**\n * 実行結果\n * @typedef {Object} SystemExecResult\n * @property {string} out\n * @property {string} error\n * @property {number} exit_code\n */\n\n/**\n * システム用のクラス\n * - 文字列の入出力\n * - スリープ、停止\n * - GUIモード、CUIモードの切り替え\n * - バッチファイルへの引数の情報\n * - カレントディレクトリ情報\n */\nexport default class System {\n\n\t/**\n\t * 文字列を表示(最終行で自動で改行されない)\n\t * @param {any} text\n\t */\n\tstatic print(text) {\n\t\tconst output = toString(text);\n\t\tif(is_cscript) {\n\t\t\tWSH.StdOut.Write(output);\n\t\t}\n\t\telse {\n\t\t\tWScript.Echo(output);\n\t\t}\n\t}\n\n\t/**\n\t * 文字列を表示(最終行で自動で改行される)\n\t * @param {any} text\n\t */\n\tstatic println(text) {\n\t\tconst output = toString(text);\n\t\tif(is_cscript) {\n\t\t\tSystem.print(output + \"\\n\");\n\t\t}\n\t\telse {\n\t\t\tSystem.print(output);\n\t\t}\n\t}\n\n\t/**\n\t * 指定したフォーマットで整形した文字列を表示\n\t * @param {any} text \n\t * @param {...any} parm パラメータは可変引数\n\t */\n\tstatic printf() {\n\t\tconst x = [];\n\t\tfor(let i = 0 ; i < arguments.length ; i++) {\n\t\t\tx[i] = arguments[i];\n\t\t\tif(i === 0) {\n\t\t\t\tx[i] = toString(x[i]);\n\t\t\t}\n\t\t}\n\t\tSystem.println(Format.textf.apply(this, x));\n\t}\n\n\t/**\n\t * キーボードのテキスト入力を取得\n\t * @returns {string}\n\t */\n\tstatic readLine() {\n\t\treturn WScript.StdIn.ReadLine();\n\t}\n\t\n\t/**\n\t * UNIX時間をミリ秒で取得\n\t * @returns {number}\n\t */\n\tstatic currentTimeMillis() {\n\t\tconst date = new Date();\n\t\treturn date.getTime();\n\t}\n\n\t/**\n\t * 処理を一時停止\n\t * @param {number} time_sec 停止する秒数\n\t */\n\tstatic sleep(time_sec) {\n\t\tWScript.Sleep((time_sec * 1000) | 0);\n\t}\n\t\n\t/**\n\t * 処理を停止\n\t */\n\tstatic stop() {\n\t\twhile(true) {\n\t\t\tWScript.Sleep(1000);\n\t\t}\n\t}\n\t\n\t/**\n\t * ビープ音を鳴らす\n\t * @param {number} frequency_hz - 周波数\n\t * @param {number} time_sec - 鳴らす秒数\n\t */\n\tstatic beep(frequency_hz, time_sec) {\n\t\tSystem.WindowsAPI(\n\t\t\t\"kernel32.dll\",\n\t\t\t\"bool Beep(uint dwFreq, uint dwDuration)\",\n\t\t\t\"$api::Beep(\" + (frequency_hz | 0) + \", \" + ((time_sec * 1000) | 0) + \");\"\n\t\t);\n\t}\n\n\t/**\n\t * 指定したコマンドを別プロセスとして実行する\n\t * @param {string} command - コマンド\n\t * @param {number} [style=1] - 起動オプション\n\t * @param {boolean} [is_wait=false] - プロセスが終了するまで待つ\n\t */\n\tstatic run(command, style, is_wait) {\n\t\tconst NormalFocus = 1;\n\t\tconst intWindowStyle = style !== undefined ? style : NormalFocus;\n\t\tconst bWaitOnReturn = is_wait !== undefined ? is_wait : false;\n\t\tconst shell = WScript.CreateObject(\"WScript.Shell\");\n\t\t// @ts-ignore\n\t\treturn shell.Run(command, intWindowStyle, bWaitOnReturn);\n\t}\n\n\t/**\n\t * 指定したコマンドを子プロセスとして実行する\n\t * @param {string} command \n\t * @returns {SystemExecResult}\n\t */\n\tstatic exec(command) {\n\t\tconst shell = WScript.CreateObject(\"WScript.Shell\");\n\t\tconst exec = shell.Exec(command);\n\t\tconst stdin = exec.StdIn;\n\t\tconst stdout = exec.StdOut;\n\t\tconst stderr = exec.StdErr;\n\t\twhile(exec.Status === 0) {\n\t\t\tWScript.Sleep(10);\n\t\t}\n\t\tconst exit_code = exec.ExitCode;\n\t\tstdin.Close();\n\t\t// @ts-ignore\n\t\tconst out = stdout.ReadAll().replace(/\\r?\\n$/, \"\");\n\t\tstdout.Close();\n\t\t// @ts-ignore\n\t\tconst error = stderr.ReadAll().replace(/\\r?\\n$/, \"\");\n\t\tstderr.Close();\n\t\treturn {\n\t\t\texit_code : exit_code,\n\t\t\tout : out,\n\t\t\terror : error\n\t\t};\n\t}\n\t\n\t/**\n\t * 指定した変数が定義されているか調べる\n\t * @param {string} variable_name\n\t * @returns {boolean}\n\t */\n\t static isDefined(variable_name) {\n\t\treturn variable_name in globalThis;\n\t}\n\t\n\t/**\n\t * プログラムを終了させます。\n\t * @param {number} [exit_code=0] \n\t */\n\tstatic exit(exit_code) {\n\t\tWScript.Quit(exit_code ? exit_code : 0);\n\t}\n\t\n\t/**\n\t * CUIで起動しなおす\n\t * @param {boolean} [is_use_chakra] - 高速なChakraエンジンを利用する(wsfが開けなくなる)\n\t */\n\tstatic executeOnCScript(is_use_chakra) {\n\t\tconst iis_use_chakra = is_use_chakra !== undefined ? is_use_chakra : false;\n\t\tif(is_wscript) {\n\t\t\t// CScript で起動しなおす\n\t\t\tconst code = [];\n\t\t\tconst args = System.getArguments();\n\t\t\tcode.push(\"\\\"C:\\\\Windows\\\\System32\\\\cscript.exe\\\"\");\n\t\t\tcode.push(\"//NoLogo\");\n\t\t\tif(iis_use_chakra) {\n\t\t\t\tcode.push(\"//E:{16d51579-a30b-4c8b-a276-0ff4dc41e755}\");\n\t\t\t}\n\t\t\tcode.push(\"\\\"\" + WScript.ScriptFullName + \"\\\"\");\n\t\t\tfor(let i = 0; i < args.length; i++) {\n\t\t\t\tcode.push(\"\\\"\" + args[i] + \"\\\"\");\n\t\t\t}\n\t\t\tSystem.run(code.join(\" \"));\n\t\t\tSystem.exit();\n\t\t}\n\t}\n\t\n\t/**\n\t * GUIで起動しなおす\n\t */\n\tstatic executeOnWScript() {\n\t\t// cscriptで起動しているか\n\t\tif(is_cscript) {\n\t\t\t// WScript で起動しなおす\n\t\t\tconst code = [];\n\t\t\tconst args = System.getArguments();\n\t\t\tcode.push(\"\\\"C:\\\\Windows\\\\System32\\\\wscript.exe\\\"\");\n\t\t\tcode.push(\"\\\"\" + WScript.ScriptFullName + \"\\\"\");\n\t\t\tfor(let i = 0; i < args.length; i++) {\n\t\t\t\tcode.push(\"\\\"\" + args[i] + \"\\\"\");\n\t\t\t}\n\t\t\tSystem.run(code.join(\" \"));\n\t\t\tSystem.exit();\n\t\t}\n\t}\n\t\n\t/**\n\t * 指定した環境変数の値を取得する\n\t * @param {string} env_name 環境変数(%は省略可能)\n\t * @returns {string}\n\t */\n\t static getEnvironmentString(env_name) {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\tconst env_param = \"%\" + env_name.replace(/%/g, \"\") + \"%\";\n\t\tconst env_value = shell.ExpandEnvironmentStrings(env_param);\n\t\treturn env_param === env_value ? \"\" : env_value;\n\t}\n\n\t/**\n\t * スクリプトファイルへの引数を取得\n\t * @returns {string[]}\n\t */\n\tstatic getArguments() {\n\t\tconst args = [];\n\t\tfor(let i = 0; i < WScript.Arguments.length; i++) {\n\t\t\targs[i] = WScript.Arguments(i);\n\t\t}\n\t\treturn args;\n\t}\n\n\t/**\n\t * カレントディレクトリを設定\n\t * @param {string} filename\n\t */\n\tstatic setCurrentDirectory(filename) {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\tshell.CurrentDirectory = filename.toString();\n\t}\n\t\n\t/**\n\t * カレントディレクトリを取得\n\t * @returns {string}\n\t */\n\tstatic getCurrentDirectory() {\n\t\tconst shell = new ActiveXObject(\"WScript.Shell\");\n\t\treturn shell.CurrentDirectory;\n\t}\n\n\t/**\n\t * 実行中のスクリプトがあるカレントディレクトリを取得\n\t * @returns {string}\n\t */\n\tstatic getScriptDirectory() {\n\t\tconst x = WSH.ScriptFullName.match(/.*\\\\/)[0];\n\t\treturn(x.substring(0 ,x.length - 1));\n\t}\n\t\n\t/**\n\t * 実行中のスクリプトがあるディレクトリをカレントディレクトリに設定\n\t */\n\tstatic initializeCurrentDirectory() {\n\t\tconst shell = WScript.CreateObject(\"WScript.Shell\");\n\t\tshell.CurrentDirectory = System.getScriptDirectory();\n\t}\n\n\t/**\n\t * BatchScript を実行する\n\t * \n\t * @param {string} source\n\t * @param {string} [charset=\"ansi\"] - 文字コード\n\t * @returns {SystemExecResult|null}\n\t */\n\tstatic BatchScript(source, charset) {\n\t\tconst icharset = charset !== undefined ? charset.toLowerCase() : \"ansi\";\n\t\tconst is_ansi = /shift_jis|sjis|ascii|ansi/i.test(icharset);\n\t\tconst is_utf16 = /unicode|utf-16le/i.test(icharset);\n\t\tconst is_line = !/\\n/.test(source);\n\n\t\t// 改行がない場合はコマンドモードで実行する\n\t\tif(is_line) {\n\t\t\t// コマンドモードで実行する\n\t\t\tconst cmd_base = is_utf16 ? \"cmd /u /d /c\" : \"cmd /d /c\";\n\t\t\t// コマンドモードで実行するため、特定の文字をエスケープさせる\n\t\t\tconst command = cmd_base + \" \" + source;\n\t\t\tconst exec = System.exec(command);\n\t\t\treturn exec;\n\t\t}\n\t\telse {\n\t\t\tconst file = new SFile(SFile.createTempFile().getAbsolutePath() + \".bat\");\n\t\t\tlet cs;\n\t\t\tcs = is_ansi ? \"shift_jis\" : \"\";\n\t\t\tcs = is_utf16 ? \"shift_jis\" : cs;\n\t\t\tcs = cs === \"\" ? icharset : cs;\n\t\t\tconst ret = file.setTextFile(source, cs, \"\\r\\n\");\n\t\t\tif(ret === false) {\n\t\t\t\tconsole.log(cs);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst cmd_base = is_utf16 ? \"cmd /u /d /c\" : \"cmd /d /c\";\n\t\t\tconst command = cmd_base + \" \\\"\" + file + \"\\\"\";\n\t\t\tconst exec = System.exec(command);\n\t\t\tfile.remove();\n\t\t\treturn exec;\n\t\t}\n\t}\n\n\t/**\n\t * PowerShell を実行する\n\t * \n\t * @param {string} source\n\t * @returns {string}\n\t */\n\tstatic PowerShell(source) {\n\t\t// 改行がない場合はコマンドモードで実行する\n\t\tif(!/\\n/.test(source)) {\n\t\t\t// スレッドセーフモードでコマンドモードで実行する\n\t\t\tconst powershell_base = \"powershell -sta -Command\";\n\t\t\t// コマンドモードで実行するため、特定の文字をエスケープさせる\n\t\t\tconst command = (powershell_base + \" \" + source).replace(/([\\\\\"])/g, \"\\\\$1\");\n\t\t\tconst exec = System.exec(command);\n\t\t\tif(exec.exit_code !== 0) {\n\t\t\t\tconsole.log(exec.exit_code);\n\t\t\t}\n\t\t\t// 最終行を除去してなるべく1行で返す\n\t\t\treturn exec.out.replace(/\\r?\\n$/, \"\");\n\t\t}\n\t\telse {\n\t\t\tconst file = new SFile(SFile.createTempFile().getAbsolutePath() + \".ps1\");\n\t\t\tfile.setTextFile(source, \"utf-16le\", \"\\r\\n\");\n\t\t\t// 本システムでスクリプトの実行が無効になっている可能性があるため一時的に実行ポリシーを変更して実行する\n\t\t\t// ※変更しないと「ParentContainsErrorRecordException」が発生する場合がある\n\t\t\tconst powershell_base = \"powershell -NoProfile -ExecutionPolicy Unrestricted\";\n\t\t\tconst command = powershell_base + \" \\\"\" + file + \"\\\"\";\n\t\t\tconst exec = System.exec(command);\n\t\t\tfile.remove();\n\t\t\tif(exec.exit_code !== 0) {\n\t\t\t\tconsole.log(exec.exit_code);\n\t\t\t}\n\t\t\treturn exec.out;\n\t\t}\n\t}\n\n\t/**\n\t * WindowsAPI を実行する\n\t * \n\t * 例\n\t * - `dll_name` : `\"user32.dll\"`\n\t * - `function_text` : `\"int MessageBox(IntPtr hWnd, string lpText, string lpCaption, UInt32 uType)\"\"`\n\t * - `exec_text` : `\"$api::MessageBox(0, \\\"テキスト\\\", \\\"キャプション\\\", 0);\"`\n\t * @param {string} dll_name - 利用するdll\n\t * @param {string} function_text - 関数の定義データ(`$api`に代入されます。)\n\t * @param {string} exec_text - 実行コマンド\n\t * @returns {string}\n\t */\n\tstatic WindowsAPI(dll_name, function_text, exec_text) {\n\t\t// 利用例\n\t\t// System.WindowsAPI(\n\t\t// \t\"user32.dll\",\n\t\t// \t\"int MessageBox(IntPtr hWnd, string lpText, string lpCaption, UInt32 uType)\",\n\t\t// \t\"$api::MessageBox(0, \\\"テキスト\\\", \\\"キャプション\\\", 0);\"\n\t\t// );\n\t\t//\n\n\t\t/*\n\t\t\tPowerShell 2.0 の Add-Type を使用している\n\t\t\t$api = Add-Type -Name \"api\" -MemberDefinition '\n\t\t\t\t[DllImport(\"user32.dll\")] public extern static int MessageBox(IntPtr hWnd, string lpText, string lpCaption, UInt32 uType);\n\t\t\t' -PassThru;\n\t\t\t$api::MessageBox(0, \\\"テキスト\\\", \\\"キャプション\\\", 0);\n\t\t*/\n\n\t\t// ダブルクォーテーションだとエスケープが面倒なので、ここはシングルクォーテーションを使用する\n\t\t// eslint-disable-next-line quotes\n\t\tconst api_base = `$api = Add-Type -Name \"api\" -MemberDefinition \"[DllImport(\"\"` + dll_name + `\"\")] public extern static ` + function_text + `;\" -PassThru;`;\n\t\tconst command = api_base + \" \" + exec_text;\n\t\treturn System.PowerShell(command);\n\t}\n\n\t/**\n\t * クリップボードからテキストを取得する\n\t * @returns {string}\n\t */\n\tstatic getClipBoardText() {\n\t\t/*\n\t\t\tAdd-Type -Assembly System.Windows.Forms;\n\t\t\t[System.Windows.Forms.Clipboard]::GetText();\n\t\t*/\n\t\tconst command = \"Add-Type -Assembly System.Windows.Forms; [System.Windows.Forms.Clipboard]::GetText();\";\n\t\treturn System.PowerShell(command);\n\t}\n\n\t/**\n\t * クリップボードへテキストを設定する\n\t * @param {string} text\n\t */\n\tstatic setClipBoardText(text) {\n\t\t/*\n\t\t\tAdd-Type -Assembly System.Windows.Forms;\n\t\t\t[System.Windows.Forms.Clipboard]::SetText(\\\"\" + text + \"\\\", 1);\n\t\t*/\n\t\tconst command = \"Add-Type -Assembly System.Windows.Forms; [System.Windows.Forms.Clipboard]::SetText(\\\"\" + text + \"\\\", 1);\";\n\t\t// PowerShell 5.0以降\n\t\t// command = \"Set-Clipboard \\\"これでもコピー可能\\\"\";\n\t\tSystem.PowerShell(command);\n\t}\n\n\t/**\n\t * `XMLHttpRequest` を作成\n\t * - 取得できない場合は `null`\n\t * \n\t * @returns {XMLHttpRequest}\n\t */\n\t static createXMLHttpRequest() {\n\t\ttry {\n\t\t\treturn new XMLHttpRequest();\n\t\t}\n\t\tcatch (e) {\n\t\t\tconst MSXMLHTTP = [\n\t\t\t\t\"WinHttp.WinHttpRequest.5.1\",\n\t\t\t\t\"WinHttp.WinHttpRequest.5\",\n\t\t\t\t\"WinHttp.WinHttpRequest\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.6.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.5.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.4.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP.3.0\",\n\t\t\t\t\"Msxml2.ServerXMLHTTP\",\n\t\t\t\t\"Microsoft.ServerXMLHTTP\",\n\t\t\t\t\"Msxml2.XMLHTTP.6.0\",\n\t\t\t\t\"Msxml2.XMLHTTP.5.0\",\n\t\t\t\t\"Msxml2.XMLHTTP.4.0\",\n\t\t\t\t\"Msxml2.XMLHTTP.3.0\",\n\t\t\t\t\"Msxml2.XMLHTTP\",\n\t\t\t\t\"Microsoft.XMLHTTP\"\n\t\t\t];\n\t\t\t// ※ WinHttp.WinHttpRequest は onreadystatechange の書き換えができない\n\t\t\tfor(let i = 0; i < MSXMLHTTP.length; i++) {\n\t\t\t\ttry {\n\t\t\t\t\treturn new ActiveXObject(MSXMLHTTP[i]);\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * `MSXML2.DOMDocument` を作成\n\t * - 取得できない場合は `null`\n\t * \n\t * @returns {any}\n\t */\n\t static createMSXMLDOMDocument() {\n\t\tconst MSXMLDOM = [\n\t\t\t\"Msxml2.DOMDocument.6.0\",\n\t\t\t\"Msxml2.DOMDocument.3.0\",\n\t\t\t\"Msxml2.DOMDocument\",\n\t\t\t\"Microsoft.XMLDOM\"\n\t\t];\n\t\tfor(let i = 0; i < MSXMLDOM.length; i++) {\n\t\t\ttry {\n\t\t\t\treturn new ActiveXObject(MSXMLDOM[i]);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * `Byte 配列` から数値配列を作成する\n\t * - `ADODB.Stream` などを用いて取得したバイナリ配列を `JavaScript` でも扱える型へ変更する\n\t * \n\t * @param {any} byte_array\n\t * @returns {number[]}\n\t */\n\tstatic createNumberArrayFromByteArray(byte_array) {\n\t\tconst dom = System.createMSXMLDOMDocument();\n\t\tif(dom === null) {\n\t\t\tconsole.log(\"createMSXMLDOMDocument\")\n\t\t\treturn [];\n\t\t}\n\n\t\t// バイト配列から16進数テキストへ変換\n\t\t// 参考\n\t\t// https://qiita.com/tnakagawa/items/9bcc26b501f5b995d896\n\t\tconst element = dom.createElement(\"hex\");\n\t\telement.dataType = \"bin.hex\";\n\t\telement.nodeTypedValue = byte_array;\n\t\t/**\n\t\t * @type {string}\n\t\t */\n\t\tconst hex_text = element.text;\n\t\tconst out = new Array(hex_text.length / 2);\n\t\t// バイト文字列から配列へ変更\n\t\tfor(let i = 0; i < out.length; i++) {\n\t\t\tout[i] = Number.parseInt(hex_text.substr(i * 2, 2), 16);\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * 数値配列から`Byte 配列`を作成する\n\t * - `ADODB.Stream` などを用いて取得したバイナリ配列を `JavaScript` でも扱える型へ変更する\n\t * - `offset` を指定した場合は、出力したバイト配列はその位置までは `NUL` で埋まった配列となる\n\t * \n\t * @param {number[]} number_array\n\t * @param {number} [offset = 0]\n\t * @returns {any}\n\t */\n\t static createByteArrayFromNumberArray(number_array, offset) {\n\t\tconst dom = System.createMSXMLDOMDocument();\n\t\tif(dom === null) {\n\t\t\tconsole.log(\"createMSXMLDOMDocument\")\n\t\t\treturn null;\n\t\t}\n\t\tlet max_size = offset !== undefined ? offset : 0;\n\t\tlet hex_string = [];\n\t\t// offsetが設定されている場合は、オフセット位置まで00で埋める\n\t\tlet p;\n\t\tfor(p = 0; p < max_size; p++) {\n\t\t\thex_string[p] = \"00\";\n\t\t}\n\t\tmax_size += number_array.length;\n\t\t// 16進数の文字列を作成する\n\t\tfor(let i = 0; p < max_size; i++, p++) {\n\t\t\tif(number_array[i] < 16) {\n\t\t\t\thex_string[p] = \"0\" + number_array[i].toString(16);\n\t\t\t}\n\t\t\telse {\n\t\t\t\thex_string[p] = number_array[i].toString(16);\n\t\t\t}\n\t\t}\n\t\t// バイト配列から16進数テキストへ変換\n\t\t// 参考\n\t\t// https://qiita.com/tnakagawa/items/9bcc26b501f5b995d896\n\t\tconst element = dom.createElement(\"hex\");\n\t\telement.dataType = \"bin.hex\";\n\t\telement.text = hex_string.join(\"\");\n\t\tconst byte_array = element.nodeTypedValue;\n\t\treturn byte_array;\n\t}\n\n\t/**\n\t * データの型を小文字の英字で返す\n\t * - 配列であれば `array`、正規表現であれば `regexp` などを返します\n\t * \n\t * @param {any} x\n\t * @returns {string}\n\t */\n\tstatic typeOf(x) {\n\t\treturn Object.prototype.toString.call(x).slice(8, -1).toLowerCase();\n\t}\n\n}\n\n\n", "static": true, "longname": "D:/JavaScript/SenkoWSH/src/senko/System.js", "access": "public", @@ -8607,7 +8621,7 @@ "lineNumber": 1 }, { - "__docId__": 241, + "__docId__": 242, "kind": "variable", "name": "is_wscript", "memberof": "src/senko/System.js", @@ -8630,7 +8644,7 @@ "ignore": true }, { - "__docId__": 242, + "__docId__": 243, "kind": "variable", "name": "is_cscript", "memberof": "src/senko/System.js", @@ -8653,7 +8667,7 @@ "ignore": true }, { - "__docId__": 243, + "__docId__": 244, "kind": "function", "name": "toString", "memberof": "src/senko/System.js", @@ -8687,7 +8701,7 @@ "ignore": true }, { - "__docId__": 244, + "__docId__": 245, "kind": "typedef", "name": "SystemExecResult", "memberof": "src/senko/System.js", @@ -8736,7 +8750,7 @@ } }, { - "__docId__": 245, + "__docId__": 246, "kind": "class", "name": "System", "memberof": "src/senko/System.js", @@ -8751,7 +8765,7 @@ "interface": false }, { - "__docId__": 246, + "__docId__": 247, "kind": "method", "name": "print", "memberof": "src/senko/System.js~System", @@ -8777,7 +8791,7 @@ "return": null }, { - "__docId__": 247, + "__docId__": 248, "kind": "method", "name": "println", "memberof": "src/senko/System.js~System", @@ -8803,7 +8817,7 @@ "return": null }, { - "__docId__": 248, + "__docId__": 249, "kind": "method", "name": "printf", "memberof": "src/senko/System.js~System", @@ -8839,7 +8853,7 @@ "return": null }, { - "__docId__": 249, + "__docId__": 250, "kind": "method", "name": "readLine", "memberof": "src/senko/System.js~System", @@ -8867,7 +8881,7 @@ "params": [] }, { - "__docId__": 250, + "__docId__": 251, "kind": "method", "name": "currentTimeMillis", "memberof": "src/senko/System.js~System", @@ -8895,7 +8909,7 @@ "params": [] }, { - "__docId__": 251, + "__docId__": 252, "kind": "method", "name": "sleep", "memberof": "src/senko/System.js~System", @@ -8921,7 +8935,7 @@ "return": null }, { - "__docId__": 252, + "__docId__": 253, "kind": "method", "name": "stop", "memberof": "src/senko/System.js~System", @@ -8936,7 +8950,7 @@ "return": null }, { - "__docId__": 253, + "__docId__": 254, "kind": "method", "name": "beep", "memberof": "src/senko/System.js~System", @@ -8972,7 +8986,7 @@ "return": null }, { - "__docId__": 254, + "__docId__": 255, "kind": "method", "name": "run", "memberof": "src/senko/System.js~System", @@ -9026,7 +9040,7 @@ } }, { - "__docId__": 255, + "__docId__": 256, "kind": "method", "name": "exec", "memberof": "src/senko/System.js~System", @@ -9065,7 +9079,7 @@ } }, { - "__docId__": 256, + "__docId__": 257, "kind": "method", "name": "isDefined", "memberof": "src/senko/System.js~System", @@ -9104,7 +9118,7 @@ } }, { - "__docId__": 257, + "__docId__": 258, "kind": "method", "name": "exit", "memberof": "src/senko/System.js~System", @@ -9132,7 +9146,7 @@ "return": null }, { - "__docId__": 258, + "__docId__": 259, "kind": "method", "name": "executeOnCScript", "memberof": "src/senko/System.js~System", @@ -9158,7 +9172,7 @@ "return": null }, { - "__docId__": 259, + "__docId__": 260, "kind": "method", "name": "executeOnWScript", "memberof": "src/senko/System.js~System", @@ -9173,7 +9187,7 @@ "return": null }, { - "__docId__": 260, + "__docId__": 261, "kind": "method", "name": "getEnvironmentString", "memberof": "src/senko/System.js~System", @@ -9212,7 +9226,7 @@ } }, { - "__docId__": 261, + "__docId__": 262, "kind": "method", "name": "getArguments", "memberof": "src/senko/System.js~System", @@ -9240,7 +9254,7 @@ "params": [] }, { - "__docId__": 262, + "__docId__": 263, "kind": "method", "name": "setCurrentDirectory", "memberof": "src/senko/System.js~System", @@ -9266,7 +9280,7 @@ "return": null }, { - "__docId__": 263, + "__docId__": 264, "kind": "method", "name": "getCurrentDirectory", "memberof": "src/senko/System.js~System", @@ -9294,7 +9308,7 @@ "params": [] }, { - "__docId__": 264, + "__docId__": 265, "kind": "method", "name": "getScriptDirectory", "memberof": "src/senko/System.js~System", @@ -9322,7 +9336,7 @@ "params": [] }, { - "__docId__": 265, + "__docId__": 266, "kind": "method", "name": "initializeCurrentDirectory", "memberof": "src/senko/System.js~System", @@ -9337,7 +9351,7 @@ "return": null }, { - "__docId__": 266, + "__docId__": 267, "kind": "method", "name": "BatchScript", "memberof": "src/senko/System.js~System", @@ -9389,7 +9403,7 @@ } }, { - "__docId__": 267, + "__docId__": 268, "kind": "method", "name": "PowerShell", "memberof": "src/senko/System.js~System", @@ -9428,7 +9442,7 @@ } }, { - "__docId__": 268, + "__docId__": 269, "kind": "method", "name": "WindowsAPI", "memberof": "src/senko/System.js~System", @@ -9487,7 +9501,7 @@ } }, { - "__docId__": 269, + "__docId__": 270, "kind": "method", "name": "getClipBoardText", "memberof": "src/senko/System.js~System", @@ -9515,7 +9529,7 @@ "params": [] }, { - "__docId__": 270, + "__docId__": 271, "kind": "method", "name": "setClipBoardText", "memberof": "src/senko/System.js~System", @@ -9541,7 +9555,7 @@ "return": null }, { - "__docId__": 271, + "__docId__": 272, "kind": "method", "name": "createXMLHttpRequest", "memberof": "src/senko/System.js~System", @@ -9569,7 +9583,7 @@ "params": [] }, { - "__docId__": 272, + "__docId__": 273, "kind": "method", "name": "createMSXMLDOMDocument", "memberof": "src/senko/System.js~System", @@ -9597,7 +9611,7 @@ "params": [] }, { - "__docId__": 273, + "__docId__": 274, "kind": "method", "name": "createNumberArrayFromByteArray", "memberof": "src/senko/System.js~System", @@ -9636,7 +9650,7 @@ } }, { - "__docId__": 274, + "__docId__": 275, "kind": "method", "name": "createByteArrayFromNumberArray", "memberof": "src/senko/System.js~System", @@ -9687,7 +9701,46 @@ } }, { - "__docId__": 275, + "__docId__": 276, + "kind": "method", + "name": "typeOf", + "memberof": "src/senko/System.js~System", + "generator": false, + "async": false, + "static": true, + "longname": "src/senko/System.js~System.typeOf", + "access": "public", + "description": "データの型を小文字の英字で返す\n- 配列であれば `array`、正規表現であれば `regexp` などを返します", + "lineNumber": 610, + "unknown": [ + { + "tagName": "@returns", + "tagValue": "{string}" + } + ], + "params": [ + { + "nullable": null, + "types": [ + "any" + ], + "spread": false, + "optional": false, + "name": "x", + "description": "" + } + ], + "return": { + "nullable": null, + "types": [ + "string" + ], + "spread": false, + "description": "" + } + }, + { + "__docId__": 277, "kind": "file", "name": "src/SenkoWSH.js", "content": "/**\n * The script is part of SenkoWSH.\n * \n * AUTHOR:\n * natade (http://twitter.com/natadea)\n * \n * LICENSE:\n * The MIT license https://opensource.org/licenses/MIT\n */\n\nimport Polyfill from \"./senko/polyfill/Polyfill.js\";\nimport typeCSV from \"./senko/CSV.js\";\nimport typeDialog from \"./senko/Dialog.js\";\nimport typeSFile from \"./senko/SFile.js\";\nimport typeRobot from \"./senko/Robot.js\";\nimport typeFormat from \"./senko/Format.js\";\nimport typeRandom from \"./konpeito/Random.js\";\nimport typeJapanese from \"./mojijs/Japanese.js\";\nimport typeStringComparator from \"./mojijs/StringComparator.js\";\nimport typeSystem from \"./senko/System.js\";\n\n/**\n * SenkoWSH\n */\n// @ts-ignore\n// eslint-disable-next-line no-undef\nconst SenkoWSH = {\n\t\n\t/**\n \t * @type {typeof typeCSV}\n\t */\n\tCSV : typeCSV,\n\t\n\t/**\n \t * @type {typeof typeDialog}\n\t */\n\tDialog : typeDialog,\n\n\t/**\n \t * @type {typeof typeSFile}\n\t */\n\t SFile : typeSFile,\n\n\t/**\n \t * @type {typeof typeRobot}\n\t */\n\t Robot : typeRobot,\n\n\t/**\n \t * @type {typeof typeFormat}\n\t */\n\t Format : typeFormat,\n\n\t/**\n \t * @type {typeof typeRandom}\n\t */\n\t Random : typeRandom,\n\n\t/**\n \t * @type {typeof typeJapanese}\n\t */\n\t Japanese : typeJapanese,\n\n\t/**\n \t * @type {typeof typeStringComparator}\n\t */\n\t StringComparator : typeStringComparator,\n\n\t/**\n \t * @type {typeof typeSystem}\n\t */\n\t System : typeSystem,\n\n};\n\nexport default SenkoWSH;\n\nif(!(typeSystem.isDefined(\"CSV\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tCSV = typeCSV;\n}\n\nif(!(typeSystem.isDefined(\"Dialog\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tDialog = typeDialog;\n}\n\nif(!(typeSystem.isDefined(\"SFile\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tSFile = typeSFile;\n}\n\nif(!(typeSystem.isDefined(\"Robot\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tRobot = typeRobot;\n}\n\nif(!(typeSystem.isDefined(\"Format\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tFormat = typeFormat;\n}\n\nif(!(typeSystem.isDefined(\"Random\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tRandom = typeRandom;\n}\n\nif(!(typeSystem.isDefined(\"Japanese\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tJapanese = typeJapanese;\n}\n\nif(!(typeSystem.isDefined(\"StringComparator\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tStringComparator = typeStringComparator;\n}\n\nif(!(typeSystem.isDefined(\"System\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-undef\n\tSystem = typeSystem;\n}\n\nif(!(typeSystem.isDefined(\"console\"))) {\n\t// @ts-ignore\n\t// eslint-disable-next-line no-global-assign\n\tglobal.console = {}\n}\n\nif(console.log === undefined) {\n\t// @ts-ignore\n\tconsole.log = function(text) {\n\t\tif((/cscript\\.exe$/i.test(WSH.FullName))) {\n\t\t\ttypeSystem.println(text);\n\t\t}\n\t}\n}\n\n", @@ -9698,7 +9751,7 @@ "lineNumber": 1 }, { - "__docId__": 276, + "__docId__": 278, "kind": "variable", "name": "SenkoWSH", "memberof": "src/SenkoWSH.js", @@ -9726,7 +9779,7 @@ }, { "kind": "packageJSON", - "content": "{\n\t\"name\": \"senkowsh\",\n\t\"version\": \"4.1.1\",\n\t\"description\": \"JScirpt library for WSH that gathers various functions.\",\n\t\"author\": \"natade-jp (https://github.com/natade-jp)\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/natade-jp/SenkoWSH\"\n\t},\n\t\"license\": \"MIT\",\n\t\"main\": \"./build/SenkoWSH.js\",\n\t\"keywords\": [\n\t\t\"wsh\"\n\t],\n\t\"directories\": {\n\t\t\"src\": \"src\",\n\t\t\"build\": \"build\",\n\t\t\"example\": \"examples\"\n\t},\n\t\"scripts\": {\n\t\t\"build\": \"node ./scripts/package.build.js\",\n\t\t\"dts\": \"node ./scripts/package.dts.js\",\n\t\t\"doc\": \"node ./scripts/package.doc.js\",\n\t\t\"start\": \"node ./scripts/execExample.js\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@types/windows-script-host\": \"^5.8.3\",\n\t\t\"esdoc\": \"^1.1.0\",\n\t\t\"esdoc-standard-plugin\": \"^1.0.0\",\n\t\t\"eslint\": \"^6.5.1\",\n\t\t\"jsdoc\": \"^3.6.3\",\n\t\t\"jsdoc-export-default-interop\": \"^0.3.1\",\n\t\t\"mojijs\": \"^3.0.3\",\n\t\t\"rollup\": \"^1.23.1\",\n\t\t\"rollup-plugin-buble\": \"^0.19.8\",\n\t\t\"rollup-plugin-uglify\": \"^6.0.3\",\n\t\t\"rollup-plugin-uglify-es\": \"0.0.1\",\n\t\t\"tsd-jsdoc\": \"^2.4.0\"\n\t}\n}\n", + "content": "{\n\t\"name\": \"senkowsh\",\n\t\"version\": \"4.2.0\",\n\t\"description\": \"JScirpt library for WSH that gathers various functions.\",\n\t\"author\": \"natade-jp (https://github.com/natade-jp)\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/natade-jp/SenkoWSH\"\n\t},\n\t\"license\": \"MIT\",\n\t\"main\": \"./build/SenkoWSH.js\",\n\t\"keywords\": [\n\t\t\"wsh\"\n\t],\n\t\"directories\": {\n\t\t\"src\": \"src\",\n\t\t\"build\": \"build\",\n\t\t\"example\": \"examples\"\n\t},\n\t\"scripts\": {\n\t\t\"build\": \"node ./scripts/package.build.js\",\n\t\t\"dts\": \"node ./scripts/package.dts.js\",\n\t\t\"doc\": \"node ./scripts/package.doc.js\",\n\t\t\"start\": \"node ./scripts/execExample.js\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@types/windows-script-host\": \"^5.8.3\",\n\t\t\"esdoc\": \"^1.1.0\",\n\t\t\"esdoc-standard-plugin\": \"^1.0.0\",\n\t\t\"eslint\": \"^6.5.1\",\n\t\t\"jsdoc\": \"^3.6.3\",\n\t\t\"jsdoc-export-default-interop\": \"^0.3.1\",\n\t\t\"mojijs\": \"^3.0.3\",\n\t\t\"rollup\": \"^1.23.1\",\n\t\t\"rollup-plugin-buble\": \"^0.19.8\",\n\t\t\"rollup-plugin-uglify\": \"^6.0.3\",\n\t\t\"rollup-plugin-uglify-es\": \"0.0.1\",\n\t\t\"tsd-jsdoc\": \"^2.4.0\"\n\t}\n}\n", "longname": "D:\\JavaScript\\SenkoWSH\\package.json", "name": "package.json", "static": true, diff --git a/docs/script/search_index.js b/docs/script/search_index.js index fe6185f..820cdff 100644 --- a/docs/script/search_index.js +++ b/docs/script/search_index.js @@ -1307,6 +1307,12 @@ window.esdocSearchIndex = [ "src/senko/System.js~System.stop", "method" ], + [ + "src/senko/system.js~system.typeof", + "class/src/senko/System.js~System.html#static-method-typeOf", + "src/senko/System.js~System.typeOf", + "method" + ], [ "src/senko/system.js~systemexecresult", "typedef/index.html#static-typedef-SystemExecResult", diff --git a/docs/source.html b/docs/source.html index e6809a5..741553c 100644 --- a/docs/source.html +++ b/docs/source.html @@ -59,7 +59,7 @@ -

Source 187/187

+

Source 188/188

@@ -150,17 +150,17 @@ - - - + + + - - - - + + + + diff --git a/package.json b/package.json index 1bc7988..d0c93dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "senkowsh", - "version": "4.1.1", + "version": "4.2.0", "description": "JScirpt library for WSH that gathers various functions.", "author": "natade-jp (https://github.com/natade-jp)", "repository": { diff --git a/src/senko/SFile.js b/src/senko/SFile.js index 06eebb2..f2d0142 100644 --- a/src/senko/SFile.js +++ b/src/senko/SFile.js @@ -118,32 +118,55 @@ export default class SFile { /** * ファイルの移動 - * @param {string|SFile} file_obj + * - 移動後の `this` は、移動後のファイルを指す + * - `this` がファイルの場合、ディレクトリを選択すると、ディレクトリ内へファイルを移動させます + * - `this` がファイルの場合、ファイルを選択すると、ディレクトリの移動かつファイル名を変更します + * - `this` がディレクトリの場合、指定したディレクトリへファイルを移動させるため、ディレクトリ名の変更は行えません + * + * @param {string|SFile} file_obj - 移動先のファイル名及びディレクトリ * @returns {boolean} */ move(file_obj) { if(this.is_http) { throw "IllegalMethod"; } - const file = new SFile(file_obj); - if(this.isFile()) { - this.fso.MoveFile(this.pathname, file.getAbsolutePath()); - this.pathname = file.getAbsolutePath(); - return true; - } - else if(this.isDirectory()) { - this.fso.MoveFolder(this.pathname, file.getAbsolutePath()); - this.pathname = file.getAbsolutePath(); - return true; + const folder = new SFile(file_obj); + try { + if(this.isFile()) { + if(!folder.isDirectory()) { + // ディレクトリを指していない場合は、移動 + ファイル名の変更 + this.fso.MoveFile(this.pathname, folder.getAbsolutePath()); + this.pathname = folder.getAbsolutePath(); + } + else { + // 宛先がディレクトリ内へ移動になる + this.fso.MoveFile(this.pathname, folder.getAbsolutePath() + "\\"); + this.pathname = folder.getAbsolutePath() + "/" + this.getName(); + } + return true; + } + else if(this.isDirectory()) { + // フォルダを指定したフォルダ内へ移動 + this.fso.MoveFolder(this.getAbsolutePath(), folder.getAbsolutePath() + "/"); + this.pathname = folder.getAbsolutePath() + "/" + this.getName(); + return true; + } + else { + return false; + } } - else { + catch (e) { + console.log(e); return false; } } /** * ファイル名を変更 - * @param {string|SFile} file_obj + * - 変更後の `this` は、変更後のファイルを指す + * - 引数はフルパスを渡した場合でもファイル名のみ使用する + * + * @param {string|SFile} file_obj 変更後のファイル名 * @returns {boolean} */ renameTo(file_obj) { @@ -153,16 +176,27 @@ export default class SFile { if(!this.isFile() && !this.isDirectory()) { return false; } - const file = this.isFile() ? this.fso.GetFile(this.pathname) : this.fso.GetFolder(this.pathname); - const name = new SFile(file_obj); - // 例えばファイル名を大文字から小文字に変換といった場合、 - // Scripting.FileSystemObject の仕様によりエラーが発生するため、 - // 別のファイル名を経由する - const key = ((Math.random() * 0x7FFFFFFF) & 0x7FFFFFFF).toString(16); - file.Name = name.getName() + key; - file.Name = name.getName(); - this.pathname = name.getAbsolutePath(); - return true; + // `GetFile` や `GetFolder` のプロパティ `.Name` で名前を変更した場合、 + // 例えばファイル名を大文字から小文字に変更すると + // `Scripting.FileSystemObject` の仕様によりエラーが発生する + // そのため `MoveFile`, `MoveFolder` を使用する + try { + // getAbsolutePath で取得すると同一名のファイルが正しく取得できないので + // 直接作成する + const dst = this.getParent() + "\\" + new SFile(file_obj).getName(); + if(this.isFile()) { + this.fso.MoveFile(this.getAbsolutePath(), dst); + } + else if(this.isDirectory()) { + this.fso.MoveFolder(this.getAbsolutePath(), dst); + } + this.pathname = new SFile(dst).getAbsolutePath(); + return true; + } + catch (e) { + console.log(e); + return false; + } } /** @@ -193,7 +227,9 @@ export default class SFile { /** * 親フォルダの絶対パス - * URLなら最後にスラッシュをつけて返す + * - 通常のフォルダの場合は、最後の「`/`」は除去される + * - URLなら最後にスラッシュをつけて返す + * * @returns {string} */ getParent() { @@ -1267,39 +1303,75 @@ export default class SFile { /** * 指定した条件にあうファイルを探す - * 関数を指定する場合は、ファイル名とフルパスが引数に渡されます - * @param {string|SFile|function(string, string): boolean} file_obj - * @returns {SFile|null} + * - 関数を指定する場合は、ファイル名とフルパスが引数に渡されます + * + * @param {string|SFile|RegExp|function(SFile): boolean} file_obj + * @param {boolean} [is_all_file=false] trueで指定した場合は条件に合うファイルを複数見つけて配列で返す + * @returns {SFile|SFile[]|null} */ - searchFile(file_obj) { - let target_file = null; + searchFile(file_obj, is_all_file) { + const is_all_file_ = is_all_file !== undefined ? is_all_file : false; + /** - * @type {function(string, string): boolean} + * @type {function(SFile): boolean} * @private */ let isTarget; if(typeof file_obj !== "function") { - const file = new SFile(file_obj); - const buffer = file.getName(); - isTarget = function(name, fullpath) { - return name === buffer; - }; + if(System.typeOf(file_obj) === "regexp") { + /** + * @type {RegExp} + */ + // @ts-ignore + const reg = file_obj; + isTarget = function(file) { + const result = reg.exec(file.getAbsolutePath()); + return result !== null; + }; + } + else { + // @ts-ignore + const file = new SFile(file_obj); + const buffer = file.getName(); + isTarget = function(file) { + return file.getName() === buffer; + }; + } } else { isTarget = file_obj; } + /** + * @type {SFile} + */ + let target_file = null; + /** + * @type {SFile[]} + */ + let target_files = []; /** * @type {function(SFile): boolean} */ const func = function(file) { - if(isTarget(file.getName(), file.getAbsolutePath())) { - target_file = file; - return false; + if(isTarget(file)) { + if(is_all_file_) { + target_files.push(file); + return true; + } + else { + target_file = file; + return false; + } } return true; }; this.each(func); - return target_file; + if(is_all_file_) { + return target_files; + } + else { + return target_file; + } } /** diff --git a/src/senko/System.js b/src/senko/System.js index b2eabaf..8ad17d4 100644 --- a/src/senko/System.js +++ b/src/senko/System.js @@ -600,6 +600,17 @@ export default class System { return byte_array; } + /** + * データの型を小文字の英字で返す + * - 配列であれば `array`、正規表現であれば `regexp` などを返します + * + * @param {any} x + * @returns {string} + */ + static typeOf(x) { + return Object.prototype.toString.call(x).slice(8, -1).toLowerCase(); + } + }
src/senko/SFile.js SFile 100 %49/4940832 byte15272021-05-04 09:31:09 (UTC)43098 byte15982021-05-04 11:45:37 (UTC)
src/senko/System.js System100 %33/3316631 byte6052021-05-02 14:10:15 (UTC)100 %34/3416923 byte6162021-05-04 09:53:12 (UTC)
src/senko/polyfill/ExtendsArray.js