1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

コマンドライン文字列の解析

Last updated at Posted at 2024-02-08

コマンドライン文字列の解析

  • 単純に空白で区切ると、二重引用符で囲まれたパスが正しく分割できない

やりたいこと

入力

この文字列を

"C:\Program Files\Hoge\Fuga.exe" /opt1

出力

このように解析

要素
0 C:\Program Files\Hoge\Fuga.exe
1 /opt1

解決策1:System.CommandLine.dll で解析

  • System.CommandLinenugetで追加
using System.CommandLine.Parsing; // 拡張メソッドを使用するために必要

static string[] Parse_CommandLineDLL(string text)
{
    return new Parser().Parse(text).Tokens.Select(token => token.Value).ToArray();
}

解決策2:Win32API で解析

static class NativeMethods
{
  [DllImport("shell32.dll", SetLastError = true)]
  public static extern IntPtr CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);

  [DllImport("kernel32.dll")]
  public static extern IntPtr LocalFree(IntPtr hMem);
}
static string[] Parse_Win32API(string text)
{
  var argsPtr = NativeMethods.CommandLineToArgvW(text, out var argsNum);
  if (argsPtr == IntPtr.Zero) throw new ArgumentException("Unable to split argument.", new Win32Exception());
  try
  {
    return Enumerable
      .Range(0, argsNum)
      .Select(i => Marshal.PtrToStringUni(Marshal.ReadIntPtr(argsPtr, i * IntPtr.Size)))
      .ToArray();
  }
  finally
  {
    NativeMethods.LocalFree(argsPtr);
  }
}

解決策3:正規表現で解析

static string[] Parse_RegEx(string text)
{
  return Regex.Matches(text, @"("".*?""|[^ ""]+)+").OfType<Match>()
              .Select(m => m.Groups[0].Value)
              .ToArray();
}

まとめ

解決策 メリット デメリット
解決策1 MS公式 余計なライブラリが増える
netstandard2.0ornet6が必要
解決策2 MS公式
ライブラリ不要
Win32API
解決策3 ライブラリ不要
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?