Compare commits
1 Commits
playWithAp
...
f26c3a3060
Author | SHA1 | Date | |
---|---|---|---|
f26c3a3060 |
@ -109,13 +109,6 @@ public sealed class AppxPackage
|
|||||||
var properties = reader.GetProperties();
|
var properties = reader.GetProperties();
|
||||||
|
|
||||||
properties.GetStringValue("DisplayName", out var displayName);
|
properties.GetStringValue("DisplayName", out var displayName);
|
||||||
|
|
||||||
if(displayName.StartsWith("ms-resource:"))
|
|
||||||
{
|
|
||||||
var packageFullName = Marshal.PtrToStringUni(info.packageFullName);
|
|
||||||
displayName = LoadResourceString(fullName, displayName);
|
|
||||||
|
|
||||||
}
|
|
||||||
package.DisplayName = displayName;
|
package.DisplayName = displayName;
|
||||||
|
|
||||||
properties.GetStringValue("Logo", out var logo);
|
properties.GetStringValue("Logo", out var logo);
|
||||||
@ -165,40 +158,6 @@ public sealed class AppxPackage
|
|||||||
ClosePackageInfo(infoRef);
|
ClosePackageInfo(infoRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static string LoadResourceString(string packageFullName, string resource)
|
|
||||||
{
|
|
||||||
if (packageFullName == null)
|
|
||||||
throw new ArgumentNullException("packageFullName");
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(resource))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
const string resourceScheme = "ms-resource:";
|
|
||||||
if (!resource.StartsWith(resourceScheme))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
string part = resource.Substring(resourceScheme.Length);
|
|
||||||
string url;
|
|
||||||
|
|
||||||
if (part.StartsWith("/"))
|
|
||||||
{
|
|
||||||
url = resourceScheme + "//" + part;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
url = resourceScheme + "///resources/" + part;
|
|
||||||
}
|
|
||||||
|
|
||||||
string source = string.Format("@{{{0}? {1}}}", packageFullName, url);
|
|
||||||
var sb = new StringBuilder(1024);
|
|
||||||
int i = SHLoadIndirectString(source, sb, sb.Capacity, IntPtr.Zero);
|
|
||||||
if (i != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace FocusVolumeControl.AudioHelpers;
|
namespace FocusVolumeControl.AudioHelpers;
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ public class AudioHelper
|
|||||||
|
|
||||||
static object _lock = new object();
|
static object _lock = new object();
|
||||||
int[] _currentProcesses;
|
int[] _currentProcesses;
|
||||||
int _retryFallbackCount = 0;
|
|
||||||
|
|
||||||
public IAudioSession Current { get; private set; }
|
public IAudioSession Current { get; private set; }
|
||||||
|
|
||||||
@ -39,7 +37,6 @@ public class AudioHelper
|
|||||||
|
|
||||||
public IAudioSession FindSession(List<Process> processes)
|
public IAudioSession FindSession(List<Process> processes)
|
||||||
{
|
{
|
||||||
//var blah = new AudioPolicyConfigFactoryImplFor21H2();
|
|
||||||
var results = new ActiveAudioSessionWrapper();
|
var results = new ActiveAudioSessionWrapper();
|
||||||
Process bestProcessMatch = null;
|
Process bestProcessMatch = null;
|
||||||
|
|
||||||
@ -52,10 +49,9 @@ public class AudioHelper
|
|||||||
deviceCollection.Item(d, out var device);
|
deviceCollection.Item(d, out var device);
|
||||||
|
|
||||||
Guid iid = typeof(IAudioSessionManager2).GUID;
|
Guid iid = typeof(IAudioSessionManager2).GUID;
|
||||||
device.Activate(ref iid, CLSCTX.ALL, IntPtr.Zero, out var m);
|
device.Activate(ref iid, 0, IntPtr.Zero, out var m);
|
||||||
var manager = (IAudioSessionManager2)m;
|
var manager = (IAudioSessionManager2)m;
|
||||||
|
|
||||||
device.GetId(out var currentDeviceId);
|
|
||||||
|
|
||||||
manager.GetSessionEnumerator(out var sessionEnumerator);
|
manager.GetSessionEnumerator(out var sessionEnumerator);
|
||||||
|
|
||||||
@ -74,16 +70,6 @@ public class AudioHelper
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
blah.GetPersistedDefaultAudioEndpoint(sessionProcessId, DataFlow.Render, Role.Multimedia, out var persistedDeviceId);
|
|
||||||
persistedDeviceId = UnpackDeviceId(persistedDeviceId);
|
|
||||||
if(!string.IsNullOrEmpty(persistedDeviceId) && persistedDeviceId != currentDeviceId)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
var index = processes.FindIndex(x => x.Id == sessionProcessId || x.ProcessName == audioProcess?.ProcessName);
|
var index = processes.FindIndex(x => x.Id == sessionProcessId || x.ProcessName == audioProcess?.ProcessName);
|
||||||
|
|
||||||
if (index > -1)
|
if (index > -1)
|
||||||
@ -128,18 +114,10 @@ public class AudioHelper
|
|||||||
var processes = GetPossibleProcesses();
|
var processes = GetPossibleProcesses();
|
||||||
var processIds = processes?.Select(x => x.Id).ToArray();
|
var processIds = processes?.Select(x => x.Id).ToArray();
|
||||||
|
|
||||||
//_currentProcesses null - first time getting sessions
|
if (_currentProcesses == null || !_currentProcesses.SequenceEqual(processIds))
|
||||||
//_currentProcesses not equal to processIds - changed the active process
|
|
||||||
//_retryFallbackCount - some processes like chrome or minecraft will start their audio process when they first try to do some sound stuff
|
|
||||||
if (_currentProcesses == null || !_currentProcesses.SequenceEqual(processIds) || _retryFallbackCount == 5)
|
|
||||||
{
|
{
|
||||||
_retryFallbackCount = 0;
|
|
||||||
Current = FindSession(processes);
|
Current = FindSession(processes);
|
||||||
}
|
}
|
||||||
else if(Current is SystemSoundsAudioSession || Current is SystemVolumeAudioSession)
|
|
||||||
{
|
|
||||||
_retryFallbackCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Current == null)
|
if (Current == null)
|
||||||
{
|
{
|
||||||
@ -236,7 +214,7 @@ public class AudioHelper
|
|||||||
deviceCollection.Item(d, out var device);
|
deviceCollection.Item(d, out var device);
|
||||||
|
|
||||||
Guid iid = typeof(IAudioSessionManager2).GUID;
|
Guid iid = typeof(IAudioSessionManager2).GUID;
|
||||||
device.Activate(ref iid, CLSCTX.ALL, IntPtr.Zero, out var m);
|
device.Activate(ref iid, 0, IntPtr.Zero, out var m);
|
||||||
var manager = (IAudioSessionManager2)m;
|
var manager = (IAudioSessionManager2)m;
|
||||||
|
|
||||||
|
|
||||||
@ -267,7 +245,7 @@ public class AudioHelper
|
|||||||
|
|
||||||
|
|
||||||
Guid iid = typeof(IAudioSessionManager2).GUID;
|
Guid iid = typeof(IAudioSessionManager2).GUID;
|
||||||
device.Activate(ref iid, CLSCTX.ALL, IntPtr.Zero, out var m);
|
device.Activate(ref iid, 0, IntPtr.Zero, out var m);
|
||||||
var manager = (IAudioSessionManager2)m;
|
var manager = (IAudioSessionManager2)m;
|
||||||
|
|
||||||
|
|
||||||
@ -293,130 +271,10 @@ public class AudioHelper
|
|||||||
deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia, out var device);
|
deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia, out var device);
|
||||||
|
|
||||||
Guid iid = typeof(IAudioEndpointVolume).GUID;
|
Guid iid = typeof(IAudioEndpointVolume).GUID;
|
||||||
device.Activate(ref iid, CLSCTX.ALL, IntPtr.Zero, out var o);
|
device.Activate(ref iid, 0, IntPtr.Zero, out var o);
|
||||||
var endpointVolume = (IAudioEndpointVolume)o;
|
var endpointVolume = (IAudioEndpointVolume)o;
|
||||||
|
|
||||||
return new SystemVolumeAudioSession(endpointVolume);
|
return new SystemVolumeAudioSession(endpointVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AudioPolicyConfigFactoryImplFor21H2
|
|
||||||
{
|
|
||||||
private readonly IAudioPolicyConfigFactoryVariantFor21H2 _factory;
|
|
||||||
|
|
||||||
internal AudioPolicyConfigFactoryImplFor21H2()
|
|
||||||
{
|
|
||||||
var iid = typeof(IAudioPolicyConfigFactoryVariantFor21H2).GUID;
|
|
||||||
Combase.RoGetActivationFactory("Windows.Media.Internal.AudioPolicyConfig", ref iid, out object factory);
|
|
||||||
_factory = (IAudioPolicyConfigFactoryVariantFor21H2)factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint ClearAllPersistedApplicationDefaultEndpoints()
|
|
||||||
{
|
|
||||||
return _factory.ClearAllPersistedApplicationDefaultEndpoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetPersistedDefaultAudioEndpoint(int processId, DataFlow flow, Role role, out string deviceId)
|
|
||||||
{
|
|
||||||
return _factory.GetPersistedDefaultAudioEndpoint(processId, flow, role, out deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint SetPersistedDefaultAudioEndpoint(int processId, DataFlow flow, Role role, IntPtr deviceId)
|
|
||||||
{
|
|
||||||
return _factory.SetPersistedDefaultAudioEndpoint(processId, flow, role, deviceId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Guid("ab3d4648-e242-459f-b02f-541c70306324")]
|
|
||||||
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
|
|
||||||
public interface IAudioPolicyConfigFactoryVariantFor21H2
|
|
||||||
{
|
|
||||||
int __incomplete__add_CtxVolumeChange();
|
|
||||||
int __incomplete__remove_CtxVolumeChanged();
|
|
||||||
int __incomplete__add_RingerVibrateStateChanged();
|
|
||||||
int __incomplete__remove_RingerVibrateStateChange();
|
|
||||||
int __incomplete__SetVolumeGroupGainForId();
|
|
||||||
int __incomplete__GetVolumeGroupGainForId();
|
|
||||||
int __incomplete__GetActiveVolumeGroupForEndpointId();
|
|
||||||
int __incomplete__GetVolumeGroupsForEndpoint();
|
|
||||||
int __incomplete__GetCurrentVolumeContext();
|
|
||||||
int __incomplete__SetVolumeGroupMuteForId();
|
|
||||||
int __incomplete__GetVolumeGroupMuteForId();
|
|
||||||
int __incomplete__SetRingerVibrateState();
|
|
||||||
int __incomplete__GetRingerVibrateState();
|
|
||||||
int __incomplete__SetPreferredChatApplication();
|
|
||||||
int __incomplete__ResetPreferredChatApplication();
|
|
||||||
int __incomplete__GetPreferredChatApplication();
|
|
||||||
int __incomplete__GetCurrentChatApplications();
|
|
||||||
int __incomplete__add_ChatContextChanged();
|
|
||||||
int __incomplete__remove_ChatContextChanged();
|
|
||||||
[PreserveSig]
|
|
||||||
uint SetPersistedDefaultAudioEndpoint(int processId, DataFlow flow, Role role, IntPtr deviceId);
|
|
||||||
[PreserveSig]
|
|
||||||
uint GetPersistedDefaultAudioEndpoint(int processId, DataFlow flow, Role role, [Out, MarshalAs(UnmanagedType.HString)] out string deviceId);
|
|
||||||
[PreserveSig]
|
|
||||||
uint ClearAllPersistedApplicationDefaultEndpoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Guid("2a59116d-6c4f-45e0-a74f-707e3fef9258")]
|
|
||||||
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
|
|
||||||
public interface IAudioPolicyConfigFactoryVariantForDownlevel
|
|
||||||
{
|
|
||||||
int __incomplete__add_CtxVolumeChange();
|
|
||||||
int __incomplete__remove_CtxVolumeChanged();
|
|
||||||
int __incomplete__add_RingerVibrateStateChanged();
|
|
||||||
int __incomplete__remove_RingerVibrateStateChange();
|
|
||||||
int __incomplete__SetVolumeGroupGainForId();
|
|
||||||
int __incomplete__GetVolumeGroupGainForId();
|
|
||||||
int __incomplete__GetActiveVolumeGroupForEndpointId();
|
|
||||||
int __incomplete__GetVolumeGroupsForEndpoint();
|
|
||||||
int __incomplete__GetCurrentVolumeContext();
|
|
||||||
int __incomplete__SetVolumeGroupMuteForId();
|
|
||||||
int __incomplete__GetVolumeGroupMuteForId();
|
|
||||||
int __incomplete__SetRingerVibrateState();
|
|
||||||
int __incomplete__GetRingerVibrateState();
|
|
||||||
int __incomplete__SetPreferredChatApplication();
|
|
||||||
int __incomplete__ResetPreferredChatApplication();
|
|
||||||
int __incomplete__GetPreferredChatApplication();
|
|
||||||
int __incomplete__GetCurrentChatApplications();
|
|
||||||
int __incomplete__add_ChatContextChanged();
|
|
||||||
int __incomplete__remove_ChatContextChanged();
|
|
||||||
[PreserveSig]
|
|
||||||
uint SetPersistedDefaultAudioEndpoint(int processId, DataFlow flow, Role role, IntPtr deviceId);
|
|
||||||
[PreserveSig]
|
|
||||||
uint GetPersistedDefaultAudioEndpoint(int processId, DataFlow flow, Role role, [Out, MarshalAs(UnmanagedType.HString)] out string deviceId);
|
|
||||||
[PreserveSig]
|
|
||||||
uint ClearAllPersistedApplicationDefaultEndpoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Combase
|
|
||||||
{
|
|
||||||
[DllImport("combase.dll", PreserveSig = false)]
|
|
||||||
public static extern void RoGetActivationFactory(
|
|
||||||
[MarshalAs(UnmanagedType.HString)] string activatableClassId,
|
|
||||||
[In] ref Guid iid,
|
|
||||||
[Out, MarshalAs(UnmanagedType.IInspectable)] out Object factory);
|
|
||||||
|
|
||||||
[DllImport("combase.dll", PreserveSig = false)]
|
|
||||||
public static extern void WindowsCreateString(
|
|
||||||
[MarshalAs(UnmanagedType.LPWStr)] string src,
|
|
||||||
[In] uint length,
|
|
||||||
[Out] out IntPtr hstring);
|
|
||||||
}
|
|
||||||
|
|
||||||
private const string DEVINTERFACE_AUDIO_RENDER = "#{e6327cad-dcec-4949-ae8a-991e976a79d2}";
|
|
||||||
private const string DEVINTERFACE_AUDIO_CAPTURE = "#{2eef81be-33fa-4800-9670-1cd474972c3f}";
|
|
||||||
private const string MMDEVAPI_TOKEN = @"\\?\SWD#MMDEVAPI#";
|
|
||||||
private string UnpackDeviceId(string deviceId)
|
|
||||||
{
|
|
||||||
if (deviceId.StartsWith(MMDEVAPI_TOKEN)) deviceId = deviceId.Remove(0, MMDEVAPI_TOKEN.Length);
|
|
||||||
if (deviceId.EndsWith(DEVINTERFACE_AUDIO_RENDER)) deviceId = deviceId.Remove(deviceId.Length - DEVINTERFACE_AUDIO_RENDER.Length);
|
|
||||||
if (deviceId.EndsWith(DEVINTERFACE_AUDIO_CAPTURE)) deviceId = deviceId.Remove(deviceId.Length - DEVINTERFACE_AUDIO_CAPTURE.Length);
|
|
||||||
return deviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,10 @@ public class NameAndIconHelper
|
|||||||
//so you have to send some messages to the apps to get the icons.
|
//so you have to send some messages to the apps to get the icons.
|
||||||
//but they will only be 32x32 (or smaller) so we only want to use this logic for java
|
//but they will only be 32x32 (or smaller) so we only want to use this logic for java
|
||||||
//because these will be lower resolution than the normal way of getting icons
|
//because these will be lower resolution than the normal way of getting icons
|
||||||
if (process.ProcessName == "javaw" || process.ProcessName == "java" || process.ProcessName == "dotnet")
|
if (process.ProcessName == "javaw" || process.ProcessName == "java")
|
||||||
{
|
{
|
||||||
var windowHandle = process.MainWindowHandle;
|
var windowHandle = process.MainWindowHandle;
|
||||||
var lazyIcon = () => JavaIconExtractor.GetWindowBigIconWithRetry(windowHandle);
|
var lazyIcon = new Lazy<Bitmap?>(() => JavaIconExtractor.GetWindowBigIcon(windowHandle));
|
||||||
results.IconWrapper = new RawIcon(windowHandle.ToString(), lazyIcon);
|
results.IconWrapper = new RawIcon(windowHandle.ToString(), lazyIcon);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public sealed class ActiveAudioSessionWrapper : IAudioSession
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return IconWrapper?.GetIconData() ?? IconWrapper.FallbackIconData;
|
return IconWrapper?.GetIconData();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -11,32 +11,6 @@ public class MMDeviceEnumerator
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum CLSCTX : uint
|
|
||||||
{
|
|
||||||
INPROC_SERVER = 0x1,
|
|
||||||
INPROC_HANDLER = 0x2,
|
|
||||||
LOCAL_SERVER = 0x4,
|
|
||||||
INPROC_SERVER16 = 0x8,
|
|
||||||
REMOTE_SERVER = 0x10,
|
|
||||||
INPROC_HANDLER16 = 0x20,
|
|
||||||
RESERVED1 = 0x40,
|
|
||||||
RESERVED2 = 0x80,
|
|
||||||
RESERVED3 = 0x100,
|
|
||||||
RESERVED4 = 0x200,
|
|
||||||
NO_CODE_DOWNLOAD = 0x400,
|
|
||||||
RESERVED5 = 0x800,
|
|
||||||
NO_CUSTOM_MARSHAL = 0x1000,
|
|
||||||
ENABLE_CODE_DOWNLOAD = 0x2000,
|
|
||||||
NO_FAILURE_LOG = 0x4000,
|
|
||||||
DISABLE_AAA = 0x8000,
|
|
||||||
ENABLE_AAA = 0x10000,
|
|
||||||
FROM_DEFAULT_CONTEXT = 0x20000,
|
|
||||||
INPROC = INPROC_SERVER | INPROC_HANDLER,
|
|
||||||
SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER,
|
|
||||||
ALL = SERVER | INPROC_HANDLER
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DataFlow
|
public enum DataFlow
|
||||||
{
|
{
|
||||||
Render,
|
Render,
|
||||||
@ -61,13 +35,6 @@ public enum DeviceState : uint
|
|||||||
MaskAll = 0xFu
|
MaskAll = 0xFu
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AudioSessionState
|
|
||||||
{
|
|
||||||
AudioSessionStateInactive = 0,
|
|
||||||
AudioSessionStateActive = 1,
|
|
||||||
AudioSessionStateExpired = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E")]
|
[Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E")]
|
||||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
@ -95,13 +62,7 @@ public interface IMMDeviceEnumerator
|
|||||||
public interface IMMDevice
|
public interface IMMDevice
|
||||||
{
|
{
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
int Activate(ref Guid iid, CLSCTX dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
|
int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int NotImpl1();
|
|
||||||
[PreserveSig]
|
|
||||||
int GetId([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppstrId);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
@ -143,9 +104,9 @@ public interface ISimpleAudioVolume
|
|||||||
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
public interface IAudioSessionControl2
|
public interface IAudioSessionControl2
|
||||||
{
|
{
|
||||||
//elgato seems to use this to determine whether the icon should be black and white
|
// IAudioSessionControl
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
int GetState(out AudioSessionState audioSessionState);
|
int NotImpl0();
|
||||||
|
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
|
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
|
||||||
@ -173,7 +134,7 @@ public interface IAudioSessionControl2
|
|||||||
|
|
||||||
// IAudioSessionControl2
|
// IAudioSessionControl2
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
uint GetSessionIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
|
int GetSessionIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
|
||||||
|
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
int GetSessionInstanceIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
|
int GetSessionInstanceIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
|
||||||
|
@ -2,7 +2,12 @@
|
|||||||
using BitFaster.Caching.Lru;
|
using BitFaster.Caching.Lru;
|
||||||
using FocusVolumeControl.UI;
|
using FocusVolumeControl.UI;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FocusVolumeControl.AudioSession
|
namespace FocusVolumeControl.AudioSession
|
||||||
{
|
{
|
||||||
@ -69,16 +74,15 @@ namespace FocusVolumeControl.AudioSession
|
|||||||
{
|
{
|
||||||
private readonly string _data;
|
private readonly string _data;
|
||||||
|
|
||||||
public RawIcon(string name, Func<Bitmap?> getIcon)
|
public RawIcon(string name, Lazy<Bitmap?> lazyIcon)
|
||||||
{
|
{
|
||||||
_data = _iconCache.GetOrAdd(name, (key) =>
|
_data = _iconCache.GetOrAdd(name, (key) =>
|
||||||
{
|
{
|
||||||
var icon = getIcon();
|
var icon = lazyIcon.Value;
|
||||||
if (icon == null)
|
if (icon == null)
|
||||||
{
|
{
|
||||||
return FallbackIconData;
|
return FallbackIconData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon.Height < 48 && icon.Width < 48)
|
if (icon.Height < 48 && icon.Width < 48)
|
||||||
{
|
{
|
||||||
using var newImage = new Bitmap(48, 48);
|
using var newImage = new Bitmap(48, 48);
|
||||||
|
@ -6,10 +6,8 @@ internal class Program
|
|||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
// Uncomment this line of code to allow for debugging
|
// Uncomment this line of code to allow for debugging
|
||||||
//while (!System.Diagnostics.Debugger.IsAttached) { System.Threading.Thread.Sleep(100); }
|
//while (!System.Diagnostics.Debugger.IsAttached) { System.Threading.Thread.Sleep(100); }
|
||||||
#endif
|
|
||||||
|
|
||||||
SDWrapper.Run(args);
|
SDWrapper.Run(args);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ using System.Drawing;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FocusVolumeControl.UI
|
namespace FocusVolumeControl.UI
|
||||||
@ -26,22 +25,6 @@ namespace FocusVolumeControl.UI
|
|||||||
[DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
|
[DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
|
||||||
public static extern int DestroyIcon(IntPtr hIcon);
|
public static extern int DestroyIcon(IntPtr hIcon);
|
||||||
|
|
||||||
public static Bitmap? GetWindowBigIconWithRetry(IntPtr hWnd)
|
|
||||||
{
|
|
||||||
var retry = 5;
|
|
||||||
var icon = GetWindowBigIcon(hWnd);
|
|
||||||
|
|
||||||
while(icon == null || retry > 0)
|
|
||||||
{
|
|
||||||
Thread.Sleep(100);
|
|
||||||
icon = GetWindowBigIcon(hWnd);
|
|
||||||
retry--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves a big icon (32*32) of a window
|
/// Retrieves a big icon (32*32) of a window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -92,16 +92,14 @@ public partial class MainWindow : Window
|
|||||||
deviceEnumerator.EnumAudioEndpoints(DataFlow.Render, DeviceState.Active, out var deviceCollection);
|
deviceEnumerator.EnumAudioEndpoints(DataFlow.Render, DeviceState.Active, out var deviceCollection);
|
||||||
deviceCollection.GetCount(out var num);
|
deviceCollection.GetCount(out var num);
|
||||||
|
|
||||||
|
for(int i = 0; i < num; i++)
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
{
|
||||||
deviceCollection.Item(i, out var device);
|
deviceCollection.Item(i, out var device);
|
||||||
//todo: put the device name in the output
|
//todo: put the device name in the output
|
||||||
sb.AppendLine($"----");
|
sb.AppendLine("----");
|
||||||
|
|
||||||
|
|
||||||
Guid iid = typeof(IAudioSessionManager2).GUID;
|
Guid iid = typeof(IAudioSessionManager2).GUID;
|
||||||
device.Activate(ref iid, CLSCTX.ALL, IntPtr.Zero, out var m);
|
device.Activate(ref iid, 0, IntPtr.Zero, out var m);
|
||||||
var manager = (IAudioSessionManager2)m;
|
var manager = (IAudioSessionManager2)m;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user