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

In self-contained app Application.ExecutablePath returns dll #1143

Closed
shutdown256 opened this issue Jun 18, 2019 · 9 comments · Fixed by #2801
Closed

In self-contained app Application.ExecutablePath returns dll #1143

shutdown256 opened this issue Jun 18, 2019 · 9 comments · Fixed by #2801
Assignees
Labels
🪲 bug Product bug (most likely) 💥 regression-preview Regression from a preview release

Comments

@shutdown256
Copy link

I'm not sure if this is bug or by design but in a self-contained app Application.ExecutablePath return path to dll and there is no apparent way to easily get path to the executable. What is recommended way to solve this problem?

@Symbai
Copy link

Symbai commented Jun 21, 2019

I've noticed this too. I believe the executable, considering its tiny size, is just a wrapper hosting your application which is basically still the DLL. So the path of the executable of your application is the path to your dll. To me it looks like an expected behavior which is by-design.

By the way it also links to your DLL when not self contained.

@weltkante
Copy link
Contributor

weltkante commented Jun 24, 2019

I don't think its by design, but rather a side effect of .NET Core handling things differently. Application.ExecutablePath already has code to figure out the native entry point but in Desktop Framework the entry point is always in an exe because the native code to load the framework is in the OS. With .NET Core they need to have a loader separate from the OS so the entry point is in a DLL, which didn't really happen in Desktop Framework unless you were implementing a custom native runtime host (and then you already know how your application is named because you implemented the host).

I think this should be fixed, this property is commonly used when you want to restart the application, otherwise there should be an alternate API for this common use case so you don't have to fall back to unmanaged code.

@shutdown256 you can implement this yourself by invoking the unmanaged GetModuleFileName API.

@Symbai
Copy link

Symbai commented Jun 24, 2019

You don't have to fall back to unmanaged code. You simply use Path.ChangeExtension on the return of Application.ExecutablePath. I would consider it as a breaking change similar to the behavior of Process.Start where on .NET Framework it automatically uses shellexecute while on core it does not. Which means if you do Process.Start("explorer.exe") it works in .NET framework but not in .NET Core, which also was confirmed as "by design".

@weltkante
Copy link
Contributor

weltkante commented Jun 24, 2019

Well, the decision with Process.Start was that they wanted it to behave the same on all platforms, but only Windows has the ShellExecute support, so whatever choice they took it was going to be broken from the start.

The case here is different, the implementation already has code to look for the "right" return value (return the native exe e.g. when your DLL is running as a plugin in a native application) but it isn't triggered because what was previoulsy an edge case is now the common case (most people didn't write a native host which calls a main function, now you get one auto-generated).

Whether you consider it a breaking change depends on what you consider your input. If you consider the input "being a managed application" then fixing the bug is no breaking change for this input, but keeping the current behavior is a breaking change for this input. Since dotnet 3 hasn't been released and this is new API there is no breaking change within .NET Core either. The WinForms team can of course still close the issue as 'by design' but I think its possible to still fix this now.

Scenario Desktop Framework .NET Core current .NET Core with fix
managed application EXE DLL EXE
native application calling managed Main DLL DLL EXE
native application calling other managed code (e.g. plugins or COM objects) EXE EXE EXE

I'd consider row 2 to be a bug in Desktop Framework, but it was an edge case so nobody ever bothered to fix it. The fact that .NET Core makes row 2 the default is unfortunate but still fixable without negative impact for the common case.

@Symbai
Copy link

Symbai commented Jun 24, 2019

This "fix" would need to be a windows - only thing then. So it would behave differently on different OS, which you said, was the goal why shellexecute was changed, although it's a huge breaking change as it's literally never set manually to true in most source codes I've seen.

That was my thought of why this behavior could be a "by design" decision. I'm not saying that a fix doesn't make sense, rather than I believe it's not a bug but just a thing like shellexecute where, when you came from framework development you now need to deal with.

@weltkante
Copy link
Contributor

@Symbai The code for Application.ExecutableImage in WinForms is already Windows only anyways, and the Application class won't be going cross-platform anytime soon either because it is based on the Windows message loop. For cross-platform there is Assembly.GetEntryAssembly and I don't suggest to change that.

@merriemcgaw merriemcgaw added this to the 3.1 milestone Oct 4, 2019
@merriemcgaw
Copy link
Member

merriemcgaw commented Oct 17, 2019

This issue is a dup of dotnet/runtime#3704

@merriemcgaw merriemcgaw removed this from the 3.1 milestone Oct 17, 2019
@weltkante
Copy link
Contributor

weltkante commented Oct 17, 2019

@merriemcgaw are you sure? we are talking about WinForms API here, unless .NET Core changes the entire approach and no longer uses a stub exe, WinForms needs to adapt to the way .NET Core handles things.

Right now the implementation in WinForms is broken because it looks at the stub and doesn't recognize it as a managed application, thus is fooled into taking the wrong code path.

@RussKie RussKie reopened this Feb 3, 2020
@RussKie
Copy link
Member

RussKie commented Feb 4, 2020

I don't get an impression this is an issue for the Core Runtime to fix it, and it is up to us to deal with it.

RussKie added a commit to RussKie/winforms that referenced this issue Feb 4, 2020
In .NET artifacts are DLLs even for executable projects. With some automagic
they get bundled into executables.
However `Assembly.GetEntryAssembly()` always returns the dll instead of the exe.

Following the guidance from the Runtime team retrieve the path to the
executable via `GetModuleFileNameW` call.

Resolves dotnet#1143
@ghost ghost added the 🚧 work in progress Work that is current in progress label Feb 4, 2020
@RussKie RussKie added 🪲 bug Product bug (most likely) 💥 regression-preview Regression from a preview release labels Feb 4, 2020
@RussKie RussKie self-assigned this Feb 4, 2020
RussKie added a commit that referenced this issue Feb 10, 2020
In .NET artifacts are DLLs even for executable projects. With some automagic
they get bundled into executables.
However `Assembly.GetEntryAssembly()` always returns the dll instead of the exe.

Following the guidance from the Runtime team retrieve the path to the
executable via `GetModuleFileNameW` call.

Resolves #1143
@ghost ghost removed the 🚧 work in progress Work that is current in progress label Feb 10, 2020
@ghost ghost added the 🚧 work in progress Work that is current in progress label Feb 10, 2020
RussKie added a commit to RussKie/winforms that referenced this issue Feb 11, 2020
…2801)

In .NET artifacts are DLLs even for executable projects. With some automagic
they get bundled into executables.
However `Assembly.GetEntryAssembly()` always returns the dll instead of the exe.

Following the guidance from the Runtime team retrieve the path to the
executable via `GetModuleFileNameW` call.

Resolves dotnet#1143

(cherry picked from commit 2af3af9)
@ghost ghost removed the 🚧 work in progress Work that is current in progress label Feb 13, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Feb 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🪲 bug Product bug (most likely) 💥 regression-preview Regression from a preview release
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants