Compare commits

..

No commits in common. "0f7f1fffcdc793eafb4ed2fc1a37f3707891d41f" and "68d51547569407a08c3d9a55aa5bb718ac54dd94" have entirely different histories.

8 changed files with 21 additions and 128 deletions

View File

@ -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();
} }

View File

@ -12,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; }
@ -50,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);
@ -116,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)
{ {
@ -224,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;
@ -255,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;
@ -281,7 +271,7 @@ 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);

View File

@ -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);
} }

View File

@ -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);

View File

@ -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);

View File

@ -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);
} }

View File

@ -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>

View File

@ -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;