概要
shlwapi.dllのSHLoadIndirectString
関数を使用してレジストリで使用されるindirect string("@location,id"
等)を元の文字列に変換するクラスとサンプルコードです。この表記は主にレジストリで使用され、DLLに含まれる文字列リソースを参照する場合に使用されます。
クラスのソースコード
Potisan.Windows.ShellIndirectString.cs
using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Security; using System.Text; namespace Potisan.Windows.Text { public static class ShellIndirectString { [SuppressUnmanagedCodeSecurity] private static class NativeMethods { [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int SHLoadIndirectString( string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, IntPtr ppvReserved); public const int ERROR_INSUFFICIENT_BUFFER = 122; } public static string Load(string source, int expanding = 5) { var buffer = new StringBuilder(expanding); for (;;) { var hr = NativeMethods.SHLoadIndirectString( source, buffer, (uint)buffer.Capacity, IntPtr.Zero); if (hr == 0) { return buffer.ToString(); } else if (Marshal.GetLastWin32Error() != NativeMethods.ERROR_INSUFFICIENT_BUFFER) { throw new Exception( "SHLoadIndirectString関数(shlwapi.dll)が失敗しました。", new Win32Exception()); } buffer.Capacity += expanding; } } public static string LoadDefault(string source, string defaultValue, int expanding = 5) { var buffer = new StringBuilder(expanding); for (; ; ) { var hr = NativeMethods.SHLoadIndirectString( source, buffer, (uint)buffer.Capacity, IntPtr.Zero); if (hr == 0) { return buffer.ToString(); } else if (Marshal.GetLastWin32Error() != NativeMethods.ERROR_INSUFFICIENT_BUFFER) { return defaultValue; } buffer.Capacity += expanding; } } } }
サンプルコード1
sample1.cs
// // 間接文字列(@記号から始まる文字列)から対応するテキストリソースを抽出する。 // using Microsoft.Win32; using Potisan.Windows.Text; namespace ConsoleApp2 { class Program { static void Main(string[] args) { using (var key = Registry.ClassesRoot.OpenSubKey("lnkfile")) { var explorerApplicationDescriptionIndirect = (string)key.GetValue("FriendlyTypeName"); var explorerApplicationDescription = ShellIndirectString.Load(explorerApplicationDescriptionIndirect); } } } }
2021/3/10:この記事は別のブログで投稿した記事を移動したものです。