Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't debug WinformsOutOfProcessWinRTComponent -- looking for Brokered Component alternative #52

Closed
therealkenc opened this issue Aug 26, 2017 · 10 comments

Comments

@therealkenc
Copy link

I have a working Brokered Component along the lines of the MSFT article here. I have also read Adam Braden's recent post "Calling WinRT Components from a Win32 process via the Desktop Bridge" here, which references the WinformsOutOfProcessWinRTComponent sample.

I have built the sample but get an error: "The application appears to already be running" when trying to launch for debug. This is with VS 2017 15.4.0 Preview 1.0 and SDK 16210. I have tried killing the COM Surrogate, and even rebooting, to no avail.

The sample isn't quite my use case however, and uses a hand-rolled COM DLL. I am ultimately looking for is some sample or walk-though that consists of:

  • A UWP C# application containing the UX inside the app container
  • A WRT C++/CX component containing some non-UX application logic that runs outside the app container "full trust"

A WRT component running outside the sandbox that returned "hello" from a method would do.

The app won't be in the store, because the WRT component requires verboten win32 calls. How might I achieve this? The article mentions "metadata marshalling" but it is commented out in the appxmanifest here. I think the pieces are there, but I am having trouble putting them together. Any help appreciated.

@wickste
Copy link
Member

wickste commented Aug 26, 2017 via email

@therealkenc
Copy link
Author

therealkenc commented Aug 26, 2017

I looked at using an AppServiceConnection before fighting my way through the "Brokered Windows Runtime Components for a side-loaded Windows Store app" article and getting the template from for Visual Studio 2013 up on 2017.

The ValueSet API isn't rich enough for my purposes. It's a "real" WRT component with TypedEventHandlers and the like. Maybe I mis-read what AppServiceConnection can do based on the samples. Please let me know if I have. But at base I am passing around WRT COM objects. Trying to wrap and unwrap those class methods into ValueSets would be a step backwards from the Brokered Component I already have up and running.

My question is whether I can improve on my Brokered Component using "Metadata Based Marshalling (MBM)". Googling the term does get me much in the way of hits. Right now I am building proxy stubs "by hand".

Am I better off just sticking with the 2013 solution, or can my workflow (if not the component itself) be improved with the features in SDK 16257? The section headline of the article reads: "Metadata Based Marshaling – No more Proxy/Stub DLLs!" So I'm sold on the headline but don't know how to use it.

Right now my appxmanifest looks like:

    <Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>clrhost.dll</Path>
        <ActivatableClass ActivatableClassId="MyBrokeredComponent.MyService" ThreadingModel="MTA">
          <ActivatableClassAttribute Name="DesktopApplicationPath" Type="string" Value="C:\Users\there\source\repos\BrokeredComponent\Debug" />
        </ActivatableClass>
      </InProcessServer>
    </Extension>

But I have to register the dll with regsrv32 and go though the whole mdmerge business to get a consumable winmd. Has this process improved? Maybe I was reading too much hope into the article?

@therealkenc
Copy link
Author

therealkenc commented Sep 2, 2017

@wickste - Okay I have struggled with this for a week but am no further. Rather than get bogged down in Brokered Components, maybe just the baby step of getting the WinformsOutOfProcessWinRTComponent running will be a start, and we can worry about where I am trying to get to after. [Where I am trying to get to is marshal WRT objects between a UWP app and a Full Trust WRT server component.]

Trying to run the sample under Visual Studio 15.4.0 Preview 1 and SDK 10.0.16267.0 I get:

`Unable to activate Windows Store app 'c0f91aa6-1012-4d95-a8do-588a6f5fe6d1_4sdaedqydyjdm!WinFormsOOPWinRTComponenet'`.

The application appears to already be running. Close the application, and start debugging again

I have tried killing the COM Surrogate process with procexp64 (which dies on it's own anyway). I have even tried rebooting. This sample is only two months old and is the subject of this blog post by Adam Braden.

Any help would be appreciated because I am hard blocked at the moment.


winformsoutofprocesswinrtcomponent-fail-sept-1-2017

@wickste
Copy link
Member

wickste commented Sep 2, 2017 via email

@therealkenc
Copy link
Author

therealkenc commented Sep 3, 2017

@wickste @AdamBraden I managed to get a spiritual equivalent of the sample running with the Windows Application Packaging Project per Matteo Pagani's recent article. I put the result on github just to stash it somewhere. Perhaps Adam's sample broke with the recent SDK updates. Or perhaps I am missing something obvious that causes the "...application appears to already be running.." error above.

Unfortunately, having got the sample (or something like it) running, I have run headlong into back to my basic question. Adam's article states:

The server must be registered for use by the AppContainer processes, or for use by the FullTrust processes.

Okay, but then how do I marshal WinRT objects (interfaces) which perform verboten operations in and out of the AppContainer, like I am presently doing with my Brokered WinRT Component? I have no legacy code here; I would prefer to use new UWP UX elements.

Anyway, enjoy the long weekend all. Until next week.

@AdamBraden
Copy link
Contributor

The current sample for WinformsOutOfProcessWinRTComponent, does not include the Debugging project which is required if you want to F5. Its goal was to show how to build and deploy one. Since the sample was created, the new Windows Application Packaging project has come out that combines both packaging and debugging - this is a better solution and I'm glad you've discovered this and gotten it up and running with the sample.

Regarding your ultimate goal, however, we do not allow direct IPC between a FullTrust process and an AppContainer process. This needs to be brokered through AppServices. This is explicitly blocked in the platform layer because there are a lot of challenges in mixing the differences between the two models. For the Desktop Bridge, this may be the last part of your app that you'd migrate - once the client and components can move to UWP/AppContainer.

@therealkenc
Copy link
Author

therealkenc commented Sep 4, 2017

Thanks @AdamBraden

I have looked at the NorthwindSample. Yes you can encapsulate a data model in JSON. But how do I data bind a UWP UX element to the "server" side which has a Windows::Foundation::Collections::ObservableVector<T>? I could (in my head) imagine writing some kind of dispatch system on top of AppServices. "RPC on AppService". But that would be nuts...

To underline, I am not trying to migrate anything. They only reason I used a Brokered Component in the first place is I didn't want to do a green pasture project on a "legacy" UX platform.

Can you elaborate on the "challenges in mixing the differences between the two models"? If it helps to visualise, assume both the AppContainer part (which has Windows::UI::Xaml::Application) and the verboten "system" bits are all written in C++/CX. Or WRL for that matter.

Or perhaps asking the question a different way: How does Microsoft do it? Sure as heck not by passing JSON back and forth. Perhaps I am missing something fundamental?

@wickste
Copy link
Member

wickste commented Sep 5, 2017 via email

@therealkenc
Copy link
Author

What is the functionality provided by your fulltrust component?

@wickste - Yes I expected that question was coming. If I could work inside the App Container, I would of course.

Let's use a Microsoft project as an example. My use case is similar but unrelated. The Microsoft Git Virtual File System. Did they use WinRT to interface their driver? Did they use C++/CX? Nope. They used C++/CLI. It is not a "legacy" project in any sense. The thing isn't even a year old. They could marshal a filesystem over AppService in theory. No one would do that.

For my project, the most glaring problem is I need to call ZwSetEaFile() per this Dev Center post. They sent me here. I also need to write to HKEY_CURRENT_USER, because it is used for 'IPC' by a third party not in my control. That third party is Microsoft, but it could be anyone; the point is you can't "migrate" code that isn't yours. But the registry part is trivial so let's set that aside.

Given that I need to marshal something as complicated and performance sensitive as a filesystem, how do I do it? And, again, at least for my edification, how do you do it?

@therealkenc
Copy link
Author

I see this User Voice flipped status this morning. This is welcome news.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants