Grabacr07 / VirtualDesktop

C# wrapper for the Virtual Desktop API on Windows 11.
MIT License
631 stars 135 forks source link

Add support for the latest Windows 10 build #57

Open mntone opened 3 years ago

mntone commented 3 years ago

Fix issue #55 & #56.

Solve the problem of replacing the new interface in the Dev Channel. It also supports the new features.

It includes an implementation that changes the files that compile based on the Windows 10 build because of adding support the new interfaces.

  1. Build – 20206: Using the traditional interface.
  2. Build 20231 – 20279: Adding support for the new parameter (Displayed as HWND or HMONITOR, unknown details).
  3. Build 21313 – 21354: Adding support for wallpaper for each virtual desktop (Get it as file path, not tested for settings) and reorder the virtual desktop.
  4. Build 21359 –: (under investigation)

It hasn't yet been confirmed whether 20211 – 20226 use the case 1 or 2.

Note: this PR is based on the previous one #50.


55, #56 を修正します。

Dev ChannelのWindows 10で新しいインターフェイスに差し代わっている問題に対応します。 また,新しいインターフェイスで追加された機能に対応します。

新しいインターフェイスに対応するために Windows 10 のビルド番号に基づいてコンパイルするファイルを変更する実装が含まれます。

  1. Build 〜20206: 従来のインターフェイスを用いる。
  2. Build 20231〜20279: 新しい謎の引数 (HWND や HMONITOR と表示される, 詳細不明) に対応。
  3. Build 21313〜21354: 仮想デスクトップごとの壁紙(パス形式で取得・設定できる, 設定に関しては未検証) やreorder機能への対応。
  4. Build 21359〜: (調査中)

※ 20211〜20226は1と2のどちらのインターフェイスを採用しているか未確認

なお,この PR は前回の PR #50 を元に作成しています。

t1m0thyj commented 3 years ago

@mntone I'm having issues with this PR on Win10 Insiders 21390.1010. Below is the code that I'm testing with.

The first message box is shown, so multiple virtual desktops are correctly detected. But the CurrentChanged event never fires.

VirtualDesktopProvider.Default.Initialize().Wait();
MessageBox.Show("Found " + VirtualDesktop.GetDesktops().Length.ToString() + " desktops");
VirtualDesktop.CurrentChanged += (sender, e) => MessageBox.Show("Active desktop changed");

When I run this same code on Win10 19043.1052, the CurrentChanged event fires when I switch desktops and triggers the second message box as expected.

mntone commented 3 years ago

@t1m0thyj Thank you for your comment.

I confirmed that the interface IVirtualDesktopNotification had been changed on Build 21359, 21370, 21387 & 21390 (Not confirmed for Build 21364, 21376 & 21382).

[Guid("cd403e52-deed-4c13-b437-b98380f2b1e8")]
interface IVirtualDesktopNotification : IUnknown {
    HRESULT Proc3(/* Stack Offset: 4 */ [In] IObjectArray* p0, /* Stack Offset: 8 */ [In] IVirtualDesktop* p1);
    HRESULT Proc4(/* Stack Offset: 4 */ [In] IObjectArray* p0, /* Stack Offset: 8 */ [In] IVirtualDesktop* p1, /* Stack Offset: 12 */ [In] IVirtualDesktop* p2);
    HRESULT Proc5(/* Stack Offset: 4 */ [In] IObjectArray* p0, /* Stack Offset: 8 */ [In] IVirtualDesktop* p1, /* Stack Offset: 12 */ [In] IVirtualDesktop* p2);
    HRESULT Proc6(/* Stack Offset: 4 */ [In] IObjectArray* p0, /* Stack Offset: 8 */ [In] IVirtualDesktop* p1, /* Stack Offset: 12 */ [In] IVirtualDesktop* p2);
    HRESULT Proc7(/* Stack Offset: 4 */ [In] int p0);
    HRESULT Proc8(/* Stack Offset: 4 */ [In] IObjectArray* p0, /* Stack Offset: 8 */ [In] IVirtualDesktop* p1, /* Stack Offset: 12 */ [In] int p2, /* Stack Offset: 16 */ [In] int p3);
    HRESULT Proc9(/* Stack Offset: 4 */ [In] IVirtualDesktop* p0, /* Stack Offset: 8 */ [In] HSTRING p1);
    HRESULT Proc10(/* Stack Offset: 4 */ [In] IApplicationView* p0);
    HRESULT Proc11(/* Stack Offset: 4 */ [In] IObjectArray* p0, /* Stack Offset: 8 */ [In] IVirtualDesktop* p1, /* Stack Offset: 12 */ [In] IVirtualDesktop* p2);
    HRESULT Proc12(/* Stack Offset: 4 */ [In] IVirtualDesktop* p0, /* Stack Offset: 8 */ [In] HSTRING p1);
}

I dealt with it.

Note: The method HRESULT Proc20([In] int p0) is added to interface IVirtualDesktopManagerInternal on Build 21359, 21370, 21387 & 21390.

t1m0thyj commented 3 years ago

@mntone Thanks for your quick response, I'm afraid the interface may have changed again in build 21390 because I've pulled your latest changes and the VirtualDesktop.CurrentChanged event still isn't working. I'd be glad to help if possible, but am not sure how to check for changes to the IVirtualDesktopNotification interface?

mntone commented 3 years ago

@t1m0thyj I confirmed that the event would work on build 21390. Could you tell me the IVirtualDesktopNotification interface in your environment?

I'm using OleViewDotNet to get the interface. https://github.com/tyranid/oleviewdotnet

The operation is as follows:

  1. Registry > Interfaces By Name
  2. Filter: [IVirtualDesktop] Apply > Right-click the interface and View Proxy Definition

The 32-bit version may provide more detailed information.

t1m0thyj commented 3 years ago

@mntone My IVirtualDesktopNotification interface looks exactly the same as yours, but I found the problem. I was dumb and forgot that the VirtualDesktop DLL is cached in %LocalAppData%\grabacr.net\VirtualDesktop\assemblies. After deleting the cached file and rerunning my test app, the event works now. Thank you!

NyaMisty commented 3 years ago

Maybe we can merge it as Windows 11 is quickly rolling out to both Dev and Beta channel? At least, you can kindly give some advices @Grabacr07?

sliddington commented 3 years ago

EDIT: This is not necessary if you correctly add an app.manifest - I finally worked out how to do that! However without one System.Runtime.InteropServices.RuntimeInformation.OSDescription may be a better way to get the build number - requires parsing the string though.

Not sure the best way to contribute this as I just don't get Git / GitHub yet - I came through the CVS -> SVN and then Mercurial path.

To get this branch to work for me I had to make this change because my OSBuild is still 9200 (but I'm trying to make my project work for Win 11 too (https://sourceforge.net/p/virtual-desktop-grid-switcher/). All the functionality I need seems to work.

image

Should I just try to push this to PR - suspect that isn't the way things work!

anaisbetts commented 3 years ago

Unfortunately as of 22449 this is broken again, here's an example stack:

ested exception -------------------------------------------------------------
Exception object: 0000021c169e04a8
Exception type:   System.Runtime.InteropServices.COMException
Message:          A null reference pointer was passed to the stub. (Exception from HRESULT: 0x800706F4)
InnerException:   <none>
StackTrace (generated):
    SP               IP               Function
    000000585FCFB580 00007FF7CDCCF6CD VirtualDesktop_21c2ef70000!WindowsDesktop.Interop.ComInterfaceWrapperBase.Invoke[[System.__Canon, mscorlib]](System.Object[], System.String)+0x19d
    000000585FCFDF20 00007FF7CDCCF3FE VirtualDesktop_21c2ef70000!WindowsDesktop.Interop.VirtualDesktopManagerInternal21313+<GetDesktops>d__3.MoveNext()+0x9e
    000000585FCFDF80 00007FFFE3EB333E System_Core_ni!System.Linq.Buffer`1[[System.__Canon, mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1<System.__Canon>)+0x9e
    000000585FCFE010 00007FFFE3EAFC4D System_Core_ni!System.Linq.Enumerable.ToArray[[System.__Canon, mscorlib]](System.Collections.Generic.IEnumerable`1<System.__Canon>)+0x5d
    000000585FCFE080 00007FF7CDCCEEDF Peach!Peach.VirtualDesktopUtilities.GetCurrentDesktops()+0x5f
    000000585FCFE0D0 00007FF7CDCCE9DD System_Reactive_21c2f0b0000!System.Reactive.Linq.ObservableImpl.Select`2+Selector+_[[System.Reactive.Unit, System.Reactive],[System.__Canon, mscorlib]].OnNext(System.Reactive.Unit)+0x2d
    000000585FCF9150 00007FFFE5548EE0 mscorlib_ni!System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()+0x20
    000000585FCF9180 00007FF7CDCD037A System_Reactive_21c2f0b0000!System.Reactive.Stubs+<>c.<.cctor>b__2_1(System.Exception)+0x3a
    000000585FCF91B0 00007FF7CDCCFBD5 System_Reactive_21c2f0b0000!System.Reactive.AnonymousSafeObserver`1[[System.__Canon, mscorlib]].OnError(System.Exception)+0x45
    000000585FCF91F0 00007FF7CDAD8AC6 System_Reactive_21c2f0b0000!System.Reactive.Sink`1[[System.__Canon, mscorlib]].ForwardOnError(System.Exception)+0x46
    000000585FCF9240 00007FF7CDCCFA35 System_Reactive_21c2f0b0000!System.Reactive.Subjects.Subject`1[[System.__Canon, mscorlib]].OnError(System.Exception)+0xc5
    000000585FCF92D0 00007FF7CDAD8AC6 System_Reactive_21c2f0b0000!System.Reactive.Sink`1[[System.__Canon, mscorlib]].ForwardOnError(System.Exception)+0x46
    000000585FCF9320 00007FF7CDAD8AC6 System_Reactive_21c2f0b0000!System.Reactive.Sink`1[[System.__Canon, mscorlib]].ForwardOnError(System.Exception)+0x46
    000000585FCF9370 00007FF7CDCCEA0B System_Reactive_21c2f0b0000!System.Reactive.Linq.ObservableImpl.Select`2+Selector+_[[System.Reactive.Unit, System.Reactive],[System.__Canon, mscorlib]].OnNext(System.Reactive.Unit)+0x5b
    000000585FCFE110 00007FF7CDCCE6D7 System_Reactive_21c2f0b0000!System.Reactive.ObserveOnObserverNew`1[[System.Reactive.Unit, System.Reactive]].DrainStep(System.Collections.Concurrent.ConcurrentQueue`1<System.Reactive.Unit>)+0x127
    000000585FCFE170 00007FF7CDCCE528 System_Reactive_21c2f0b0000!System.Reactive.ObserveOnObserverNew`1[[System.Reactive.Unit, System.Reactive]].DrainShortRunning(System.Reactive.Concurrency.IScheduler)+0x18
    000000585FCFE1B0 00007FF7CDCCE4B6 System_Reactive_21c2f0b0000!System.Reactive.Concurrency.DispatcherScheduler+<>c__DisplayClass12_0`1[[System.__Canon, mscorlib]].<Schedule>b__0()+0x46
NyaMisty commented 3 years ago

Well we should probably consider this repo as abandoned / discontinued. How about bringing it to a new repo (like @mntone 's)?

NyaMisty commented 3 years ago

@anaisbetts I've re-adapted @mntone's fork to 22454 https://github.com/mntone/VirtualDesktop/pull/1

sliddington commented 3 years ago

Well we should probably consider this repo as abandoned / discontinued. How about bringing it to a new repo (like @mntone 's)?

Yes, I was thinking the same.