我们在.NET 3.5应用程序中使用CSLA(一个相当古老的版本),我们为一些用户使用它的NetRun应用程序加载。对于那些不熟悉NetRun的人来说,NetRun.exe基本上是安装在用户计算机上的应用程序“跑步者”(例如,安装到c:\ Program Files \ NetRun \ NetRun.exe)。用户只需启动NetRun.exe即可启动应用程序。
NetRun.exe的作用如下:
(1)创建一个新的AppDomainSetup
Dim setupDomain As New AppDomainSetup()
setupDomain.ApplicationBase = CurrentDomainPath() ' this will be C:\Program Files\NetRun\
setupDomain.ConfigurationFile = "http://www.ourdomain.com/TheApp.xml" ' The app.config file is actually named TheApp.xml on the server because it has NetRun-specific config settings that don't belong in the standard TheApp.config that is used when the app is running directly from the server.
(2)然后使用该AppDomainSetup
创建一个新的AppDomain' create new application domain
Dim newDomain As AppDomain = AppDomain.CreateDomain("TheApp", Nothing, setupDomain)
(3)然后通过以下方式在新的AppDomain中实例化NetRun.Launcher(一个启动助手类 - 主要用于常见的启动画面):
' create launcher object in new appdomain
Dim launcher As Launcher = CType(newDomain.CreateInstanceAndUnwrap("NetRun", "NetRun.Launcher"), Launcher)
(4)然后,luncher助手类通过
在新的AppDomain中运行应用程序' use launcher object from the new domain to launch the remote app in that appdomain
launcher.RunApp()
(5)在所有启动画面之后,应用程序最终通过
启动Dim ass = Assembly.LoadFrom("http://www.ourdomain.com/TheApp.exe")
ass.EntryPoint.Invoke(ass.EntryPoint, Nothing)
因此,回顾一下,实际运行的应用程序的AppDomain的ApplicationBase是C:\ Program Files \ NetRun \,而实际应用程序的EntryPoint可以在“http://www.ourdomain.com/TheApp.exe”中找到。到目前为止,非常好。
除了TheApp.exe之外,应用程序本身也是对ALibrary.dll的依赖。到目前为止,这对我们来说非常有用。即使ALibrary.dll具有被拉入TheApp.xml文件的配置条目,这些配置条目也一直被读取(并继续这样做)。
在我们即将发布的版本中,我们添加了一个新的自定义配置文件部分,该部分在ALibrary.dll中定义。我们将新部分添加到TheApp.xml和TheApp.config文件
中<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.Applicat...">
<section name="TheApp.My.MySettings" type="System.Configuration.ClientSettingsS..."/>
<section name="ALibrary.My.MySettings" type="System.Configuration.ClientSettingsS..."/>
</sectionGroup>
<!-- NEW CONFIG SECTION -->
<section name="fixedPriceExceptionModel" type="ALibrary.Configuration.FixedPrices.FixedPriceExceptionModelSection, ALibrary"/>
</configSections>
(在这篇文章中,部分内容被用来节省空间)
但是,当我们尝试访问NetRun中的新部分时,通过“正常”方式启动TheApp.exe
CType(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) _
.GetSection("fixedPriceExceptionModel"), FixedPriceExceptionModelSection)
我们得到以下例外:
创建时出错 配置节处理程序 fixedPriceExceptionModel:不能 加载文件或程序集'ALibrary'或 其中一个依赖项。系统 找不到指定的文件。 (http://www.ourdomain.com/TheApp.xml 第8行
做一些研究,这是因为.NET配置库的程序集解析器在所有常用位置都在寻找ALibrary.dll; ApplicationBase,特定子目录,.NET核心目录,然后是GAC。不幸的是,ALibrary.dll永远不会在任何这些地方找到。当此应用程序直接在服务器上运行而没有NetRun时,应用程序不会抛出异常并正确读取配置部分。
我尝试的一件事是以不同的方式设置AppDomainSetup,因为它的ApplicationBase将设置为http://www.ourdomain.com/,但后来调用CType(newDomain.CreateInstanceAndUnwrap(“NetRun”,“NetRun.Launcher”)) ,Launcher)炸弹,因为NetRun.exe不在服务器上。
这可能需要考虑很多,我希望我能够很好地描述它(并没有让你烦恼)。也许没有简单的解决方案,但我已经用尽了我对这个领域的有限知识,并希望其他人在SO上可能有神奇的解决方案,允许我在NetRun和本地运行应用程序时可靠地访问自定义配置部分。 / p>
答案 0 :(得分:2)
据我所知,问题是,代码是在客户端机器上运行的,没有组件的真实(物理)存在,因为它们是从服务器加载的。
了解它,你有两个选择:
1.努力寻找现有代码的解决方案;)
2.不使用自定义配置节处理程序。
就个人而言,我会选择#2。
不使用ALibrary.Configuration.FixedPrices.FixedPriceExceptionModelSection作为配置节处理程序(导致异常,因为在客户端上找不到此类型),而是使用默认的System.Configuration.ClientSettingsSection,如其他部分那样 - 这是其中的一部分.NET Framework,所以在客户端没有问题。之后,为所需的配置类创建一个工厂(如果你真的需要强类型),它将逐步读取配置并创建你的FixedPriceExceptionModel对象,填充数据并可供需要它的任何东西使用。
如果我误解了这个问题,请告诉我。
答案 1 :(得分:1)
我意识到这是对已经回答的问题的回复非常晚,但我已设法使用codebase元素来解决此问题。
示例(如果需要,您也可以使用file:/// url表单):
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AssemblyName" publicKeyToken="null" culture="neutral" />
<codeBase version="1.0.0.0" href="http://server.address.com/AssemblyLocation/AssemblyName.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
另见:
答案 2 :(得分:0)
我认为这不会像你提出的那样有用。
这行代码可以工作,因为LoadFrom
是一个神奇的方法,可以查看程序集及其任何依赖项的特定位置。从这个神奇的LoadFrom上下文加载App.exe及其DLL:
Dim ass = Assembly.LoadFrom("http://www.ourdomain.com/TheApp.exe")
然而,配置部分程序集加载失败,因为加载它的.NET框架代码(可能)使用普通Assembly.Load
调用,该调用与原始LoadFrom
调用断开连接并且没有了解www.ourdomain.com。有多种方法可以将其他目录添加到.NET程序集搜索路径中,但这些都是相对于应用程序域基本目录的。
正如您所指出的,让Assembly.Load
了解www.ourdomain.com的唯一方法是更改app域基目录。在这种情况下,将NetRun.exe部署到Web服务器上是否太糟糕了?