for Push.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
using KssSmaPlaLib.Commons;
|
||||
using KssSmaPlaLib.Exchange.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace KssSmaPlaLib.IO.File
|
||||
{
|
||||
public class CsvUxer
|
||||
{
|
||||
public static bool ExportToCsv<T>(List<T> list, string filePath, out string resultMessage, EncodingUxer.EncodingType encodingType = EncodingUxer.EncodingType.Utf8WithoutBom) where T : ICsvExportableUxer
|
||||
{
|
||||
resultMessage = string.Empty;
|
||||
try
|
||||
{
|
||||
var lines = new List<string> { list.FirstOrDefault()?.CsvHeader ?? "" };
|
||||
lines.AddRange(list.Select(item => item.ToCsvLine()));
|
||||
System.IO.File.WriteAllLines(filePath, lines, EncodingUxer.GetEncoding(encodingType));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
resultMessage = $"CSV出力に失敗しました。[ファイルパス:{filePath},エラー内容:{ex.Message}]";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CSVインポート
|
||||
/// </summary>
|
||||
/// <param name="csvFilePath">CSVファイルパス</param>
|
||||
/// <param name="recordSet">[出力]レコードセット</param>
|
||||
/// <param name="resultMessage">[出力]メッセージ</param>
|
||||
/// <param name="encodingType">[オプション]エンコード</param>
|
||||
/// <returns>成否</returns>
|
||||
public static bool ImportFromCsv(string csvFilePath, out List<Dictionary<string, string>> recordSet, out string resultMessage, EncodingUxer.EncodingType encodingType = EncodingUxer.EncodingType.Utf8WithoutBom)
|
||||
{
|
||||
recordSet = new List<Dictionary<string, string>>();
|
||||
resultMessage = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 全行読み込み
|
||||
var lines = System.IO.File.ReadAllLines(csvFilePath, EncodingUxer.GetEncoding(encodingType));
|
||||
|
||||
// データ行0件
|
||||
if (lines.Length < 2) return true;
|
||||
|
||||
// ヘッダ行項目分割
|
||||
var header = Regex.Split(lines[0], ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
|
||||
for (var cnt = 0; cnt < header.Length; cnt++) header[cnt] = header[cnt].Trim('\"');
|
||||
|
||||
// データ行件数分
|
||||
for (int i = 1; i < lines.Length; i++)
|
||||
{
|
||||
// 項目分割
|
||||
var values = Regex.Split(lines[i], ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
|
||||
for (var cnt = 0; cnt < values.Length; cnt++) values[cnt] = values[cnt].Trim('\"');
|
||||
|
||||
if (values.Length != header.Length)
|
||||
{
|
||||
resultMessage = $"CSV読み込みでヘッダの項目数とデータの項目数が異なります。[CSVファイルパス:{csvFilePath},行番号:{i + 1},ヘッダ行項目数:{header.Length},データ行項目数:{values.Length}]";
|
||||
return false;
|
||||
}
|
||||
|
||||
var record = new Dictionary<string, string>();
|
||||
|
||||
// 全項目
|
||||
for (int j = 0; j < header.Length && j < values.Length; j++)
|
||||
{
|
||||
var key = header[j].Trim('\"');
|
||||
var value = values[j].Trim('\"');
|
||||
record[key] = value;
|
||||
}
|
||||
recordSet.Add(record);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
resultMessage = $"CSV読み込み処理でエラーが発生しました。[CSVファイルパス:{csvFilePath},エラー内容:{ex.Message}]";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Escape(string value) => $"\"{value.Replace("\"", "\"\"")}\"";
|
||||
// public static string Join(params object[] values) => string.Join(",", values.Select(m => Escape(m == null ? "" : m.ToString())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using DocumentFormat.OpenXml.Vml;
|
||||
using KssSmaPlaLib.Commons;
|
||||
using KssSmaPlaLib.Exchange.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace KssSmaPlaLib.IO.File
|
||||
{
|
||||
public static class FileUxer
|
||||
{
|
||||
/// <summary>
|
||||
/// テキストファイル出力(全テキスト一括)
|
||||
/// </summary>
|
||||
/// <param name="allLineText">全テキスト</param>
|
||||
/// <param name="filePath">ファイルパス</param>
|
||||
/// <param name="resultMessage">メッセージ</param>
|
||||
/// <param name="encodingType">文字コード</param>
|
||||
/// <returns>成否</returns>
|
||||
public static bool WriteAllText(string allLineText, string filePath, out string resultMessage, EncodingUxer.EncodingType encodingType = EncodingUxer.EncodingType.Utf8WithoutBom)
|
||||
{
|
||||
resultMessage = string.Empty;
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllText(filePath, allLineText, EncodingUxer.GetEncoding(encodingType));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
resultMessage = $"CSV出力に失敗しました。[ファイルパス:{filePath},エラー内容:{ex.Message}]";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryDeletePatternFiles(
|
||||
string folderPath,
|
||||
string fileNamePattern,
|
||||
out int fileCount,
|
||||
out string resultMessage)
|
||||
{
|
||||
fileCount = 0;
|
||||
resultMessage = string.Empty;
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
resultMessage = $"フォルダが存在しません。[フォルダパス:{folderPath}]";
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var files = Directory.GetFiles(folderPath, fileNamePattern);
|
||||
|
||||
foreach (var filePath in files)
|
||||
{
|
||||
System.IO.File.Delete(filePath);
|
||||
fileCount++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
resultMessage = $"ファイル削除中にエラーが発生しました。[フォルダパス:{folderPath},ファイル名パターン:{fileNamePattern},エラー内容:{ex.Message}]";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetTimestampedFileName(string originalName, DateTime dt, string prefixDtFormat, string suffixDtFormat)
|
||||
{
|
||||
string nameWithoutExt = Path.GetFileNameWithoutExtension(originalName);
|
||||
string ext = Path.GetExtension(originalName);
|
||||
string prefixDtStr = dt.ToString(prefixDtFormat);
|
||||
string suffixDtStr = dt.ToString(suffixDtFormat);
|
||||
|
||||
string newName = prefixDtStr + nameWithoutExt + suffixDtStr;
|
||||
return newName + ext;
|
||||
}
|
||||
|
||||
// public static bool CheckParentFolderExists(string folderPath, out string parentPath)
|
||||
// {
|
||||
// parentPath = Path.GetDirectoryName(folderPath) ?? string.Empty;
|
||||
// return Directory.Exists(parentPath);
|
||||
// }
|
||||
|
||||
// public static bool TryApplyActionToFiles<T>(
|
||||
// string folderPath,
|
||||
// Func<FileInfo, bool> condition,
|
||||
// Action<FileInfo> action,
|
||||
// out int fileCount,
|
||||
// out string resultMessage,
|
||||
// string actionName = "操作",
|
||||
// bool isDescending = true,
|
||||
// Func<FileInfo, T>? sortKey = null,
|
||||
// int skip = 0)
|
||||
// {
|
||||
// fileCount = 0;
|
||||
// resultMessage = string.Empty;
|
||||
|
||||
// try
|
||||
// {
|
||||
// // 条件未指定時は全件対象
|
||||
// condition = condition ?? (_ => true);
|
||||
|
||||
// // 一旦条件で取得
|
||||
// var files = new DirectoryInfo(folderPath)
|
||||
// .GetFiles()
|
||||
// .Where(condition);
|
||||
|
||||
// // ソートキー作成
|
||||
// var keySelector =
|
||||
// sortKey != null ? (Func<FileInfo, object>)
|
||||
// (f => sortKey(f)) : f => f.LastWriteTime;
|
||||
|
||||
// // ソート+スキップ+リスト化
|
||||
// var filesList =
|
||||
// (isDescending ?
|
||||
// files.OrderByDescending(keySelector) :
|
||||
// files.OrderBy(keySelector))
|
||||
// .Skip(skip)
|
||||
// .ToList();
|
||||
|
||||
// foreach (var file in filesList)
|
||||
// {
|
||||
// action(file);
|
||||
// LoggerUxer.Info($"{actionName}しました。[{file}]");
|
||||
// }
|
||||
|
||||
// fileCount = filesList.Count;
|
||||
// return true;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// resultMessage = $"ファイル群の{actionName}に失敗しました。[エラー内容:{ex.Message}]";
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace KssSmaPlaLib.IO.File
|
||||
{
|
||||
public static class JsonFileUxer
|
||||
{
|
||||
/// <summary>
|
||||
/// JSONファイルのピンポイント1項目更新
|
||||
/// </summary>
|
||||
/// <param name="path">JSONファイルパス</param>
|
||||
/// <param name="jsonPath">JSONノードパス</param>
|
||||
/// <param name="newValue">更新値</param>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
// public static void UpdateJsonKeyAtomic(string path, string jsonPath, object newValue)
|
||||
// {
|
||||
// //// 使い方例:パスワード更新
|
||||
// //JsonFiileUxer.UpdateJsonKeyAtomic("config.json", "app.auth.password", "new_pw_2026-01");
|
||||
|
||||
// var jtoken = JToken.FromObject(newValue);
|
||||
|
||||
// // 1) 読み込み(UTF-8)
|
||||
// var json = System.IO.File.ReadAllText(path, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
|
||||
// var jo = JObject.Parse(json);
|
||||
|
||||
// // 2) ピンポイント更新(途中が無ければ作る)
|
||||
// var token = jo.SelectToken(jsonPath);
|
||||
// if (token is null)
|
||||
// {
|
||||
// // 例: "app.auth.password" を分解して動的に作る
|
||||
// var parts = jsonPath.Split('.');
|
||||
// JToken cur = jo;
|
||||
// for (int i = 0; i < parts.Length; i++)
|
||||
// {
|
||||
// var name = parts[i];
|
||||
// var obj = cur as JObject ?? throw new InvalidOperationException("親がオブジェクトではありません");
|
||||
// if (i == parts.Length - 1)
|
||||
// {
|
||||
// obj[name] = jtoken;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (obj[name] == null) obj[name] = new JObject();
|
||||
// cur = obj[name];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// token.Replace(jtoken);
|
||||
// }
|
||||
|
||||
// // 3) 一時ファイルへ書き出し
|
||||
// var dir = System.IO.Path.GetDirectoryName(path) ?? ".";
|
||||
// var tmp = System.IO.Path.Combine(dir, ".tmp_config.json");
|
||||
// var backup = path + $"_{DateTime.Now.ToString("yyyyMMddHHmmss")}" + ".bak";
|
||||
|
||||
// //var output = jo.ToString(Formatting.Indented) + Environment.NewLine;
|
||||
// var output = JsonConvert.SerializeObject(jo, Formatting.Indented) + Environment.NewLine;
|
||||
// System.IO.File.WriteAllText(tmp, output, new UTF8Encoding(false));
|
||||
|
||||
// // 4) バックアップ作成 → 原子置換
|
||||
// if (System.IO.File.Exists(path)) System.IO.File.Copy(path, backup, overwrite: true);
|
||||
// System.IO.File.Replace(tmp, path, backup);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// JSONファイルから、jsonPathに一致する単一項目を取得します。
|
||||
/// 取得に成功したら true を返し、 out value に JToken を設定します。
|
||||
/// キーが見つからない・JSON無効・ファイル無し等は false を返し、 value は null。
|
||||
/// </summary>
|
||||
// public static bool TryGetJsonKey(string path, string jsonPath, out JToken value)
|
||||
// {
|
||||
// value = null;
|
||||
|
||||
// // 1) 読み込み(UTF-8 BOMなし)
|
||||
// string json;
|
||||
// try
|
||||
// {
|
||||
// json = System.IO.File.ReadAllText(path, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// // ファイルがない/読み取り不可
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // 2) 解析
|
||||
// JObject jo;
|
||||
// try
|
||||
// {
|
||||
// jo = JObject.Parse(json);
|
||||
// }
|
||||
// catch (JsonReaderException)
|
||||
// {
|
||||
// // JSON不正
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // 3) ピンポイント取得
|
||||
// // 例: "app.auth.password" / "items[0].name" / "users['alice'].age" 等
|
||||
// try
|
||||
// {
|
||||
// var token = jo.SelectToken(jsonPath);
|
||||
// if (token is null)
|
||||
// {
|
||||
// return false; // キー未存在
|
||||
// }
|
||||
|
||||
// value = token; // JValue/JObject/JArray いずれもOK
|
||||
// return true;
|
||||
// }
|
||||
// catch (ArgumentException)
|
||||
// {
|
||||
// // JSONPathの書式誤り(SelectTokenが例外)
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 文字列として取得(JToken型を意識したくない場合の軽量ヘルパー)。
|
||||
/// </summary>
|
||||
// public static bool TryGetJsonString(string path, string jsonPath, out string result)
|
||||
// {
|
||||
// result = string.Empty;
|
||||
// if (!TryGetJsonKey(path, jsonPath, out var token)) return false;
|
||||
|
||||
// // JValue以外(オブジェクト/配列)の場合は ToString() を許容するか判断(ここではJValueのみ厳密)
|
||||
// if (token is JValue jv)
|
||||
// {
|
||||
// // 文字列ならそのまま
|
||||
// if (jv.Type == JTokenType.String)
|
||||
// {
|
||||
// result = (string)jv.Value;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// // 数値・真偽・Null などは ToString() で返す設計でもOK
|
||||
// // ここでは文字列のみ厳密に true とします(お好みで分岐調整)
|
||||
// return false;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 符号付き整数(Int64)で取得(intの範囲超えも想定)。
|
||||
/// </summary>
|
||||
// public static bool TryGetJsonInt64(string path, string jsonPath, out long result)
|
||||
// {
|
||||
// result = default;
|
||||
// if (!TryGetJsonKey(path, jsonPath, out var token)) return false;
|
||||
|
||||
// if (token is JValue jv)
|
||||
// {
|
||||
// // JValueが数値型なら long へ
|
||||
// if (jv.Type == JTokenType.Integer)
|
||||
// {
|
||||
// // Newtonsoftは内部的に long を持つのでキャスト可能
|
||||
// try
|
||||
// {
|
||||
// result = Convert.ToInt64(jv.Value);
|
||||
// return true;
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 文字列数値を許可する場合("42" → 42)
|
||||
// if (jv.Type == JTokenType.String && long.TryParse((string)jv.Value, out var parsed))
|
||||
// {
|
||||
// result = parsed;
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 任意型の既定値付き取得(存在しなければ defaultValue を返す)。
|
||||
/// 例:GetJsonKeyOrDefault(path, "app.auth.retries", 3)
|
||||
/// </summary>
|
||||
// public static T GetJsonKeyOrDefault<T>(string path, string jsonPath, T defaultValue)
|
||||
// {
|
||||
// if (!TryGetJsonKey(path, jsonPath, out var token) || token is null)
|
||||
// return defaultValue;
|
||||
|
||||
// try
|
||||
// {
|
||||
// // JToken → 任意型に変換(失敗時は既定値)
|
||||
// var val = token.ToObject<T>();
|
||||
// return val == null ? defaultValue : val;
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// return defaultValue;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using KssSmaPlaLib.Commons;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace KssSmaPlaLib.IO.File
|
||||
{
|
||||
public static class PathUxer
|
||||
{
|
||||
public static string CreateFullPathEx(
|
||||
string folderPath,
|
||||
string fileName,
|
||||
string dtPrefix = "",
|
||||
string dtSuffix = "")
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
// フォルダ:未指定時はカレントフォルダ
|
||||
folderPath = string.IsNullOrEmpty(folderPath) ? "." : folderPath;
|
||||
|
||||
// ファイル名:未指定時は"noname.txt"とする
|
||||
fileName = string.IsNullOrEmpty(fileName) ? "noname.txt" : fileName;
|
||||
|
||||
if (fileName.IndexOf('.') == -1)
|
||||
{
|
||||
// 拡張子がないとき、付与する
|
||||
fileName += ".txt";
|
||||
}
|
||||
|
||||
// ファイルパス
|
||||
var path = Path.Combine(
|
||||
Path.GetFullPath(folderPath),
|
||||
(string.IsNullOrEmpty(dtPrefix) ? "" : now.ToString(dtPrefix)) +
|
||||
fileName.Split('.')[0] +
|
||||
(string.IsNullOrEmpty(dtSuffix) ? "" : now.ToString(dtSuffix)) +
|
||||
"." +
|
||||
fileName.Split('.')[1]);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static string CombineUnixPath(params string[] parts)
|
||||
{
|
||||
return string.Join("/", parts.Select(p => p.Trim('/')));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ファイル名(パス不可)を受け取り、存在すればフルパスを返す。
|
||||
/// 探索順:①このDLLのフォルダ → ②エントリEXEのフォルダ → ③AppDomain.BaseDirectory
|
||||
/// (C)昼コパソフトウェア㈱
|
||||
/// </summary>
|
||||
/// <param name="fileName">パスではないファイル名のみ(例: "config.json")。</param>
|
||||
/// <param name="fullPath">見つかったファイルのフルパス。未発見時は null。</param>
|
||||
/// <returns>発見した場合 true、未発見の場合 false。</returns>
|
||||
// public static bool TryResolveInAssemblyFolder(string fileName, out string fullPath)
|
||||
// {
|
||||
// fullPath = null;
|
||||
|
||||
// // --- ガード:パスを排除(「ファイル名のみ」の前提を厳守) ---
|
||||
// if (string.IsNullOrWhiteSpace(fileName))
|
||||
// return false;
|
||||
|
||||
// // ディレクトリ成分が入っていたら拒否
|
||||
// if (!string.Equals(fileName, Path.GetFileName(fileName), StringComparison.Ordinal))
|
||||
// return false;
|
||||
|
||||
// // 予約文字の簡易チェック(Windows前提の一般的なNG文字)
|
||||
// foreach (var ch in Path.GetInvalidFileNameChars())
|
||||
// {
|
||||
// if (fileName.IndexOf(ch) >= 0)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // --- ① このメソッドを含むライブラリ(DLL)のフォルダ ---
|
||||
// var dllFolder = SafeGetDirectoryName(SafeGetAssemblyLocation(Assembly.GetExecutingAssembly()));
|
||||
// if (TryCombineAndExists(dllFolder, fileName, out fullPath))
|
||||
// return true;
|
||||
|
||||
// // --- ② エントリアセンブリ(EXE)のフォルダ ---
|
||||
// string exeFolder = null;
|
||||
// var entry = Assembly.GetEntryAssembly();
|
||||
// if (entry != null)
|
||||
// {
|
||||
// exeFolder = SafeGetDirectoryName(SafeGetAssemblyLocation(entry));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // サービスや特殊ホストで EntryAssembly が null の場合のフォールバック
|
||||
// try
|
||||
// {
|
||||
// exeFolder = SafeGetDirectoryName(Process.GetCurrentProcess()?.MainModule?.FileName);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// // 取れないケースもあるので無理せず次へ
|
||||
// exeFolder = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (TryCombineAndExists(exeFolder, fileName, out fullPath))
|
||||
// return true;
|
||||
|
||||
// // --- ③ AppDomain 基準(ClickOnce等のケースでも安定) ---
|
||||
// var baseDir = AppDomain.CurrentDomain?.BaseDirectory;
|
||||
// if (TryCombineAndExists(baseDir, fileName, out fullPath))
|
||||
// return true;
|
||||
|
||||
// // --- 未発見 ---
|
||||
// fullPath = null;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 指定フォルダに fileName を結合し、存在すれば out に設定して true。
|
||||
/// </summary>
|
||||
// private static bool TryCombineAndExists(string folder, string fileName, out string path)
|
||||
// {
|
||||
// path = null;
|
||||
// if (string.IsNullOrWhiteSpace(folder))
|
||||
// return false;
|
||||
|
||||
// try
|
||||
// {
|
||||
// var candidate = Path.Combine(folder, fileName);
|
||||
// if (System.IO.File.Exists(candidate))
|
||||
// {
|
||||
// path = candidate;
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// // パス結合や存在確認で例外が出てもスキップして未発見扱い
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Assembly.Location を安全に取得(Reflection-only / 影響ケースを考慮)。
|
||||
/// </summary>
|
||||
// private static string SafeGetAssemblyLocation(Assembly asm)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// return asm?.Location;
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// DirectoryName を安全に取得。
|
||||
/// </summary>
|
||||
// private static string SafeGetDirectoryName(string path)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// return string.IsNullOrEmpty(path) ? null : Path.GetDirectoryName(path);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user