2

让我更好地解释我的情况。我想从网络驱动器启动 .exe。我注意到,如果您在 Win XP 任务管理器中签入,带有 1 个组件(进度条)的小型 .net 4 表单会占用大约 20mb 的内存。因此,一旦加载了启动表单,它就会在任务栏中占用大约 20mb 的内存。

因此,如果 .exe 从网络驱动器启动,客户端计算机必须等到将整个表单加载到内存中,然后才会显示出来。这大约需要 2-3 分钟。所以它必须等待 20mb 加载。从网络驱动器启动 .exe 时立即显示启动画面的最佳方法是什么?说而不是等待 20MB 完全下载,当只有不到 1MB 下载到客户端内存时,是否可以显示启动画面?您能否提供有关如何执行此操作的建议?

我通过查看客户端计算机上的任务管理器检查了这一点,直到 .exe 达到大约 20 MB,然后显示启动表单。然后它等到 .exe 达到大约 40MB 以显示主窗体。我希望从网络驱动器启动 exe 后不到两秒的时间内显示启动画面,以便用户知道 exe 将在大约 2-3 分钟内完成加载。那么如何实现呢?

顺便说一句,加载需要很长时间,因为客户端机器位于异地,并且有一个 VPN 将机器连接到中央文件服务器。这就是加载需要一段时间的原因,因为上传链接最多为 1Mb。但是一旦 .exe 完成加载,就不会出现缓慢。最好的方法是拥有终端服务或 citrix。但这暂时不是一个选择。或者在客户端机器上安装每个 .exe,但我不想走这条路。

4

5 回答 5

1

看看 ClickOnce 部署。潜在地,它将允许您保留单个网络副本以便于部署,但除非已更新,否则将避免客户端下载应用程序。

http://msdn.microsoft.com/en-us/library/t71a733d

于 2011-03-04T04:35:55.510 回答
0

.Net 运行时仅在需要时加载程序集 - 如果您使可执行文件尽可能小(只是显示启动屏幕所需的最小限度)并将其余代码放入更大的程序集中,那么理论上您的启动屏幕在需要加载较大的程序集之前可以非常快速地显示。

实现这一点的关键是了解 .Net 框架何时会尝试加载程序集——更准确地说,它将在开始执行引用该程序集中包含的类型的任何方法之前加载程序集。尝试使用以下程序来更好地理解这一点:

// Contained in FirstAssembly.exe
class Program
{
    static void Main()
    {
        PrintLoadedAssemblies("start of Main");
        innerMain();
    }

    static void innerMain()
    {
        PrintLoadedAssemblies("start of innerMain");
        OtherClass obj;
    }

    static void PrintLoadedAssemblies(string point)
    {
        Console.WriteLine("Loaded assemblies at {0}", point);
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            Console.WriteLine(assembly.FullName);
        }
    }
}

// Contained in OtherAssembly.dll
class OtherClass
{

}

有了这些知识,我们现在知道,为了在加载第二个较大的程序集之前显示启动屏幕,我们需要确保在执行引用较大程序集中任何类型的任何方法之前显示启动屏幕 - 这很难让我测试一下,但如果我们有一个相当标准的启动画面:

static void Main()
{
    Application.Run(new SplashScreen());
}

那么我们应该在更大的程序集中引用任何类型的第一点应该是在类似于SplashScreen_Shown事件的地方,比如:

void SplashScreen_Shown(object sender, EventArgs e)
{
    (new MainForm()).Show();
    this.Hide();
}

另请注意,这将发生在主 / UI 线程上,因此在加载较大的程序集时您的初始屏幕无响应 - 如果这是不可接受的,那么您需要重构上述内容,以便包含MainForm引用的方法位于异步线程中.

于 2011-03-04T07:37:18.253 回答
0

您可能会考虑构建第二个应用程序,该应用程序只执行以下操作:

  1. 显示启动画面

  2. 启动一个指向远程 exe 的新 Windows 进程。

-

我认为这个问题包含您需要的代码的近似值:

如何知道 Process.Start 何时加载 winform?

于 2011-03-04T01:53:19.923 回答
0

任务管理器进程选项卡中的内存使用仅限本地,不会从联网的计算机下载!当您从网络驱动器加载应用程序时,它仅下载可执行文件并在本地执行;这就是每个操作系统一直这样做的方式,它不在服务器上执行并流式传输。

我在这里有一个时事通讯发送应用程序,例如,15kb exe,加载时在 ram 中使用 4.3mb(大数据列表,所以这是预期的)

通过 VPN 从美国的服务器加载到我的本地计算机(我在澳大利亚的 ADSL 1,512 链接上......所以超慢!)它在大约 1-2 秒内加载应用程序并且没有办法我可以在 1 秒内下载 4.3mb... 我希望 :)

那么你能做些什么来解决你的问题呢?

如果可执行文件很大并且包含嵌入式资源(图像、视频、列表、XML 等)......您可以将它们制作为外部文件并为用户显示加载窗口,也许也可以在本地缓存文件,因此只需要完成一次,然后启动应用程序很快。可以通过应用程序检查和重新下载对资源的更改

如果应用程序可执行文件很小并且没有访问外部文件/资源​​(在网络文件夹中或在线),那么您只需管理一些网络问题:)

于 2011-03-04T06:30:56.887 回答
-1

嘿,谢谢你的回答。根据您的建议,我考虑了以下解决方案。A 已经构建了一个控制台应用程序,当您从网络驱动器启动它时,它会非常快速地启动。不到两秒。这个控制台应用程序将是我的启动画面,虽然不漂亮,但至少用户会知道发生了什么事。控制台 exe 将启动我想要真正加载的 .exe,至少用户会知道它的加载并且需要几分钟才能加载。如果可能,控制台应用程序将显示剩余时间。我现在只需要弄清楚如何使用控制台应用程序来做到这一点。加载主 .exe 后,我必须关闭控制台应用程序。

有人知道如何从控制台应用程序执行此操作吗?

于 2011-03-05T04:53:46.563 回答