【发布时间】:2010-11-02 02:03:58
【问题描述】:
可执行文件加载外部库。
库有没有办法知道调用的可执行文件?
(我发誓我在其他地方看到了这个问题的答案,但我似乎再也找不到了)
【问题讨论】:
可执行文件加载外部库。
库有没有办法知道调用的可执行文件?
(我发誓我在其他地方看到了这个问题的答案,但我似乎再也找不到了)
【问题讨论】:
除了上面的答案。
我编写了以下 test.exe 作为控制台应用程序
static void Main(string[] args) {
Console.WriteLine(
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
Console.WriteLine(
System.Reflection.Assembly.GetEntryAssembly().Location);
Console.WriteLine(
System.Reflection.Assembly.GetExecutingAssembly().Location);
Console.WriteLine(
System.Reflection.Assembly.GetCallingAssembly().Location);
}
然后我编译了项目并将其输出重命名为 test2.exe 文件。输出行正确且相同。
但是,如果我在 Visual Studio 中启动它,结果是:
d:\test2.vhost.exe
d:\test2.exe
d:\test2.exe
C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
Visual Studio 的 ReSharper 插件在
System.Diagnostics.Process.GetCurrentProcess().MainModule
尽可能 System.NullReferenceException。如果你查看 MainModule 的文档,你会发现这个属性也可以抛出 NotSupportedException、PlatformNotSupportedException 和 InvalidOperationException。
GetEntryAssembly 方法也不是 100%“安全”的。 MSDN:
GetEntryAssembly 方法在托管程序集时可以返回 null 已从非托管应用程序加载。例如,如果一个 非托管应用程序创建一个编写的 COM 组件的实例 在 C# 中,从 C# 组件调用 GetEntryAssembly 方法 返回 null,因为进程的入口点是非托管的 代码而不是托管程序集。
对于我的解决方案,我更喜欢Assembly.GetEntryAssembly().Location。
如果需要解决虚拟化的问题,则更感兴趣。例如,我们有一个项目,我们使用 Xenocode Postbuild 将 .net 代码链接到一个可执行文件中。必须重命名此可执行文件。所以上面所有的方法都不起作用,因为它们只获取原始程序集或内部进程的信息。
我找到的唯一解决方案是
var location = System.Reflection.Assembly.GetEntryAssembly().Location;
var directory = System.IO.Path.GetDirectoryName(location);
var file = System.IO.Path.Combine(directory,
System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
【讨论】:
Environment.GetCommandLineArgs()[0]
【讨论】:
static void Main(string[] args) 内应该是使用的那个。这很奇怪,因为根据我对 C++ 的记忆,第一个参数始终是可执行文件。
这个不包括在内:
System.Windows.Forms.Application.ExecutablePath;
~乔
【讨论】:
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
【讨论】:
我认为这应该是你想要的:
System.Reflection.Assembly.GetEntryAssembly().Location
这将返回进程启动时首次加载的程序集,这似乎是您想要的。
GetCallingAssembly 在一般情况下不一定会返回您想要的程序集,因为它返回的程序集包含调用堆栈中紧靠更高位置的方法(即它可能在同一个 DLL 中)。
【讨论】:
如果你想要可执行文件:
System.Reflection.Assembly.GetEntryAssembly().Location
如果您想要使用您的库的程序集(如果您的代码直接从可执行文件中的类调用,则可以是与上述相同的程序集):
System.Reflection.Assembly.GetCallingAssembly().Location
如果您只想要文件名称而不想要路径,请使用:
Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location)
【讨论】:
Assembly.GetEntryAssembly().Location 和 Assembly.GetCallingAssembly().Location 返回应用程序 .dll ,期望 .exe。
Assembly.GetEntryAssembly()
【讨论】: