C# 如果编译后program.exe名称发生更改,则无法加载资源

C# 如果编译后program.exe名称发生更改,则无法加载资源,c#,C#,我有一个非托管dll,所以我写这个是为了在程序运行后将dll保存到文件中 工作代码: public static void ExtractResourceToFile() { if (!File.Exists("loader.dll")) try { using (System.IO.FileStream fs = new System.IO.FileStream("loader.dll", System.IO.FileMode.

我有一个非托管dll,所以我写这个是为了在程序运行后将dll保存到文件中

工作代码:

public static void ExtractResourceToFile()
{
    if (!File.Exists("loader.dll"))
        try
        {

            using (System.IO.FileStream fs = new System.IO.FileStream("loader.dll", System.IO.FileMode.Create))
                System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Kraken.Resources.loader.dll").CopyTo(fs);
                Thread.Sleep(5000);

        }       
        catch ( Exception ex)
        { }
}
问题:

如果已编译的Kraken.exe名称已更改,则不会保存DLL

我所尝试的:

public static void ExtractResourceToFile()
{
    if (!File.Exists("loader.dll"))
        try
        {
            string file = System.Reflection.Assembly.GetExecutingAssembly().Location;;
            string app = System.IO.Path.GetFileNameWithoutExtension(file);
            using (System.IO.FileStream fs = new System.IO.FileStream(file, System.IO.FileMode.Create))
                System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(app + ".Resources.loader.dll").CopyTo(fs);
                Thread.Sleep(5000);

        }       
        catch ( Exception ex)
        { }
}
我还尝试获取当前进程名称并使用它,但出现了相同的问题。

请参见:

这些评论尤其有趣:

注意getExecutionGassembly():如果从库中调用此函数 程序集,它返回库程序集的名称,即 不同于入口组件的名称(即原始 可执行文件)。如果使用GetEntryAssembly(),它将返回 实际的可执行文件,但如果进程是 在WCF下运行(无可否认,这是一种罕见的情况)。对于最健壮的 代码,使用Process.GetCurrentProcess().ProcessName.–康坦戈11月3日 12点01分10点

嗯,请注意,即使重命名,返回的字符串也不会更改 使用文件资源管理器手动创建可执行文件。虽然 Environment.GetCommandLineArgs()[0]会随着实际 可执行文件名(当然)。巧合的是,第二种方法 由于我希望数据文件夹 以实际可执行文件名命名Hatoru Hansou 2014年1月23日 2点25分

Hatoru的评论似乎支持Phil1970的评论,即getExecutionGassembly()可能使用程序集中的资源属性,而不是实际的文件名

所以我会用

Process.GetCurrentProcess().ProcessName

正如孔坦戈所建议的那样

正如虫族所说,不要忽略例外情况。

请看以下内容:

这些评论尤其有趣:

注意getExecutionGassembly():如果从库中调用此函数 程序集,它返回库程序集的名称,即 不同于入口组件的名称(即原始 可执行文件)。如果使用GetEntryAssembly(),它将返回 实际的可执行文件,但如果进程是 在WCF下运行(无可否认,这是一种罕见的情况)。对于最健壮的 代码,使用Process.GetCurrentProcess().ProcessName.–康坦戈11月3日 12点01分10点

嗯,请注意,即使重命名,返回的字符串也不会更改 使用文件资源管理器手动创建可执行文件。虽然 Environment.GetCommandLineArgs()[0]会随着实际 可执行文件名(当然)。巧合的是,第二种方法 由于我希望数据文件夹 以实际可执行文件名命名Hatoru Hansou 2014年1月23日 2点25分

Hatoru的评论似乎支持Phil1970的评论,即getExecutionGassembly()可能使用程序集中的资源属性,而不是实际的文件名

所以我会用

Process.GetCurrentProcess().ProcessName

正如孔坦戈所建议的那样



正如zerkms所说,不要忽略异常。

所以你忽略抛出的异常,然后想知道它为什么不起作用?在编译时设置最终文件名,这样以后就不必更改它了。如果以后更改,我认为文件属性中的某些信息仍然具有原始名称,因此看起来不太专业。因此,您希望
GetManifestResourceStream(“foo”)
GetManifestResourceStream(“bar”)
能够一致地返回所需的流,而不考虑传递给该方法的参数是什么?请注意,程序集的名称和默认名称空间之间并没有直接关系……@AlexeiLevenkov我不太理解您,但这就是我的意思,GetManifestResourceStream()需要名称空间而不是程序集名称do
namespace.Properties.Resources.Name
是否有用?因此您忽略引发的异常,然后想知道它为什么不起作用?在编译时设置最终文件名,这样以后就不必更改它。如果以后更改,我认为文件属性中的某些信息仍然具有原始名称,因此看起来不太专业。因此,您希望
GetManifestResourceStream(“foo”)
GetManifestResourceStream(“bar”)
能够一致地返回所需的流,而不考虑传递给该方法的参数是什么?请注意,程序集的名称和默认名称空间之间并没有直接关系……@AlexeiLevenkov我不太理解您,但这就是我的意思,GetManifestResourceStream()需要名称空间而不是程序集名称do
namespace.Properties.Resources.Name
是否有用?如果您觉得链接的答案解决了问题,只需将其标记为重复即可。。。但实际上,可执行文件的名称与
GetManifestResourceStream
的参数无关……我发现有用的注释不在链接线程的标记答案中。我是否将标记为重复并留下注释?@KCWong我确实尝试过使用ProcessName,但同样的问题是,我得到的异常是:
System.NullReferenceException:Object reference未设置为对象的实例。
@meatball尝试打断行“System.Reflection.Assembly.GetExecutionGassembly()”。。。您想知道NullReferenceException是来自GetExecutionGassembly()还是GetManifestResourceStream()。您还应该尝试使用调试器,在该行上设置一个断点并单步执行。@KCI最终使用base64和GZip从代码中加载它,如果您觉得链接的答案解决了问题,只需标记为重复。。。但实际上,可执行文件的名称与
GetManifestResourceStream
的参数无关……我发现有用的注释不在链接线程的标记答案中。我是否标记为重复并留下注释?@KCWong我确实尝试过ProcessName,但同样的问题是,我得到的异常是:
System.NullReferenceException:Object reference未设置为对象的实例。
@meatball尝试打断行“Syst”