diff --git a/VRChatLogWathcer/Utils/COMObject.cs b/VRChatLogWathcer/Utils/COMObject.cs new file mode 100644 index 0000000..a2f064d --- /dev/null +++ b/VRChatLogWathcer/Utils/COMObject.cs @@ -0,0 +1,98 @@ +using System; +using System.Runtime.InteropServices; + +namespace VRChatLogWathcer.Utils +{ + /// + /// COMオブジェクトの開放処理を確実に行うためのラッパーオブジェクト + /// + internal class COMObject : IDisposable + { + private dynamic? _object; + private bool _isDisposed; + + public dynamic Object => (_isDisposed || _object is null) ? throw new ObjectDisposedException(nameof(COMObject)) : _object; + + public COMObject(dynamic comObject) + { + _object = comObject; + } + + protected virtual void Dispose(bool disposing) + { + if (!_isDisposed) + { + //if (disposing) + //{ + // // TODO: マネージド状態を破棄します (マネージド オブジェクト) + //} + + Marshal.ReleaseComObject(_object); + _object = null; + _isDisposed = true; + } + } + + ~COMObject() + { + // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します + Dispose(disposing: false); + } + + public void Dispose() + { + // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } + + /// + /// COMオブジェクトの開放処理を確実に行うためのラッパーオブジェクト + /// + /// + internal class COMObject : IDisposable + { + private dynamic? _object; + private bool _isDisposed; + + public dynamic Object => (_isDisposed || _object is null) ? throw new ObjectDisposedException(nameof(COMObject)) : _object; + + public T Casted => (T)Object; + + public COMObject(dynamic comObject) + { + _object = comObject; + } + + protected virtual void Dispose(bool disposing) + { + if (!_isDisposed) + { + //if (disposing) + //{ + // // TODO: マネージド状態を破棄します (マネージド オブジェクト) + //} + + Marshal.ReleaseComObject(_object); + _object = null; + _isDisposed = true; + } + } + + ~COMObject() + { + // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します + Dispose(disposing: false); + } + + public void Dispose() + { + // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + public static implicit operator T(COMObject obj) => obj.Casted; + } +} diff --git a/VRChatLogWathcer/Utils/ExplorerUtil.cs b/VRChatLogWathcer/Utils/ExplorerUtil.cs index e364503..682487a 100644 --- a/VRChatLogWathcer/Utils/ExplorerUtil.cs +++ b/VRChatLogWathcer/Utils/ExplorerUtil.cs @@ -1,7 +1,7 @@ -using SHDocVw; -using Shell32; -using System; +using System; +using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace VRChatLogWathcer.Utils @@ -56,25 +56,53 @@ public static bool Open(string path) /// private static bool TryGetHwndOf(string path, out IntPtr hwnd) { - var shell = new Shell(); - ShellWindows wins = shell.Windows(); - foreach (InternetExplorer win in wins) + Type? comShellType = Type.GetTypeFromProgID("Shell.Application"); + if (comShellType is null) { - if (!win.FullName.Equals(ExplorerPath, StringComparison.OrdinalIgnoreCase)) + hwnd = default; + return false; + } + + try + { + if (!TryCreateShell(comShellType, out var instance)) { - continue; + hwnd = default; + return false; } + using var shell = new COMObject(instance); + using var wins = new COMObject(shell.Object.Windows()); + using var enumerator = new COMObject(wins.Object.GetEnumerator()); - var uri = new Uri(win.LocationURL); - if (path.Equals(uri.LocalPath, StringComparison.OrdinalIgnoreCase)) + while (enumerator.Casted.MoveNext()) { - hwnd = new IntPtr(win.HWND); - return true; + using var win = new COMObject(enumerator.Casted.Current); + if (!win.Object.FullName.Equals(ExplorerPath, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + var uri = new Uri(win.Object.LocationURL); + if (path.Equals(uri.LocalPath, StringComparison.OrdinalIgnoreCase)) + { + hwnd = new IntPtr(win.Object.HWND); + return true; + } } } + catch + { + // COM関連で発生した例外は握りつぶす + } hwnd = default; return false; + + static bool TryCreateShell(Type type, [NotNullWhen(true)] out object? instance) + { + instance = Activator.CreateInstance(type); + return instance is not null; + } } private class NativeMethods diff --git a/VRChatLogWathcer/VRChatLogWathcer.csproj b/VRChatLogWathcer/VRChatLogWathcer.csproj index 7a23a92..184868c 100644 --- a/VRChatLogWathcer/VRChatLogWathcer.csproj +++ b/VRChatLogWathcer/VRChatLogWathcer.csproj @@ -12,27 +12,6 @@ - - - tlbimp - 0 - 1 - 50a7e9b0-70ef-11d1-b75a-00a0c90564fe - 0 - false - true - - - tlbimp - 1 - 1 - eab22ac0-30c1-11cf-a7eb-0000c05bae0b - 0 - false - true - - -