ASP. NET and non-hosted DLL

Source: Internet
Author: User
Document directory
  • Loading C ++ Assemblies in ASP. Net

Environment VS2010

Languages: iso c ++, C ++ \ CLI, and C # multi-language integrated programming

ASP. NET (C #) to develop a WMS server prototype, because the dll developed by standard C ++ cannot be directly referenced by C #, so it is used (similar to the effect of SWIG automatic packaging) C ++ \ CLI implements secondary encapsulation and bridging (in fact, this is also a SuperMap routine, and it is indeed different from ESRI's COM ). To solve this problem, first make a hypothesis:

(1) The underlying library is written in standard C ++. The generated DLL is called isocpp. dll, which is also called native dll and belongs to unmanaged (unmanaged) dll.

(2) To enable C # To call this isocpp. dll, I used C ++ \ CLI to encapsulate it twice. During VS2010 compilation, I opened CLR support and generated isocpp_clr.dll.

In this way, C # can directly add this dll to the reference of the project. In winForm, we only need to ensure that isocpp_clr.dll and isocpp. dll is in the same path. in the managed code of. net, classes and Methods encapsulated in isocpp_clr.dll are used. dll. Therefore, there is no problem with bridging in the desktop environment.

However, changing to the web environment of asp.net produces a disgusting problem: Unable to load the file, assembly isocpp_clr.dll, or its dependency, and throw system. io. filenotfoundexception. Note that all dll files are in the bin directory of the website, and the relative paths and absolute paths of all dll files are normal. I read a lot of information, while ASP. net team explained this problem: Because the asp.net website will copy all the files to a temporary directory on the C drive at runtime, but ASP. NET only copies the dependent hosted dll. For example, my isocpp_clr.dll can be automatically copied, however, if a hosted dll depends on some non-system Unmanaged dll, the file or assembly cannot be loaded, and the filenotfoundexception exception occurs.

It is not easy to solve this problem. At first, I thought that if DEBUG cannot be run, after the release, I put all the hosted and unmanaged dll files in the bin directory. I didn't expect that I was wrong again, and the problem remained.

Here, I have to say that the domestic network is really like a landfill. A bunch of people are searching for the landfill where ctrl c and ctrl v are located. It is really too much water and a lot of time is wasted. Finally, I found a solution on a foreigner's BLOG. In the original article, I used 2.a to solve the problem:

(1) For unmanaged dll, when C ++ \ CLI encapsulation is performed on them, the ingress command in project properties --- connector -- post built scriptof event generation calls al.exe for hosting packaging, method:

Al.exe/link: ".. \ bin \ a. dll"/out: ".. \ bin \ a_wrp.dll"/platform: x86

Al.exe/link: ".. \ bin \ B. dll"/out: ".. \ bin \ B _wrp.dll"/platform: x86

Al.exe/link: ".. \ bin \ c. dll"/out: ".. \ bin \ c_wrp.dll"/platform: x86

Other native dll...

(2) In this way, each Unmanaged dll will automatically generate a hosted dll, which is equivalent to a proxy.. net project references to ensure that these local Unmanaged dll files can be copied. The author said that it is not enough to put all the dll files in the bin directory of the website. You also need to set environment variables for the website process. However, after completing these operations, the website will run normally when I debug the local machine, which is also confusing.

(3) set a temporary environment variable for the Process of the Website: Add a Global class to the website, and add the bin directory of the current website to the PATH environment variable at the Process level in application_start, in this way, the website Program (generally dll) can find the hosted or unmanaged dll under any circumstances. My test results also prove this. Code:

Protected void Application_Start (object sender, EventArgs e ){
String _ path = String. Concat (System. Environment. GetEnvironmentVariable ("PATH"), ";", System. AppDomain. CurrentDomain. RelativeSearchPath );
System. Environment. SetEnvironmentVariable ("PATH", _ path, EnvironmentVariableTarget. Process );
}

Thanks to the original author.

BTW, spit out ms...

 

 

Http://blogs.msdn.com/ B /jorman/archive/2007/08/31/loading-c-assemblies-in-asp-net.aspx

Loading C ++ Assemblies in ASP. Net

RATE THIS

Jerry_Orman

31 Aug 2007 PM

  • 8

When you reference a Native C ++ assembly from ASP. Net you may run into the following error:

System. IO. FileNotFoundException: The specified module cocould not be found.
(Exception from HRESULT: 0x8007007E)

[FileNotFoundException: The specified module cocould not be found. (Exception from HRESULT: 0x8007007E)]
System. Reflection. Assembly. nLoad (AssemblyName fileName, String codeBase, evi1_assemblysecurity, Assembly locationHint, StackCrawlMark & stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) + 0
System. Reflection. Assembly. InternalLoad (AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark & stackMark, Boolean forIntrospection) + 211
System. Reflection. Assembly. InternalLoad (String assemblyString, Evidence assemblySecurity, StackCrawlMark & stackMark, Boolean forIntrospection) + 141
System. Reflection. Assembly. Load (String assemblyString) + 25
System. Web. Configuration. CompilationSection. LoadAssemblyHelper (String assemblyName, Boolean starDirective) + 32

[ConfigurationErrorsException: The specified module cocould not be found. (Exception from HRESULT: 0x8007007E)]
System. Web. Configuration. CompilationSection. LoadAssemblyHelper (String assemblyName, Boolean starDirective) + 596
System. Web. Configuration. CompilationSection. LoadAllAssembliesFromAppDomainBinDirectory () + 3591161
System. Web. Configuration. CompilationSection. LoadAssembly (AssemblyInfo ai) + 46
System. Web. Compilation. BuildManager. GetReferencedAssemblies (CompilationSection compConfig) + 177
System. Web. Compilation. BuildProvidersCompiler.. ctor (VirtualPath configPath, Boolean supplocallocalization, String outputAssemblyName) + 180
System. Web. Compilation. ApplicationBuildProvider. GetGlobalAsaxBuildResult (Boolean isPrecompiledApp) + 3558605
System. Web. Compilation. BuildManager. CompileGlobalAsax () + 51
System. Web. Compilation. BuildManager. EnsureTopLevelFilesCompiled () + 462

[HttpException (0x80004005): The specified module cocould not be found. (Exception from HRESULT: 0x8007007E)]
System. Web. Compilation. BuildManager. ReportTopLevelCompilationException () + 57
System. Web. Compilation. BuildManager. EnsureTopLevelFilesCompiled () + 612
System. Web. Hosting. HostingEnvironment. Initialize (ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters) + 642

[HttpException (0x80004005): The specified module cocould not be found. (Exception from HRESULT: 0x8007007E)]
System. Web. HttpRuntime. FirstRequestInit (HttpContext context) + 3539851
System. Web. HttpRuntime. EnsureFirstRequestInit (HttpContext context) + 69
System. Web. HttpRuntime. ProcessRequestInternal (HttpWorkerRequest wr) + 252

 

The core cause to this problem is in the way the operating system loads native DLL's at runtime. native DLL's are loaded using the following logic which does not include the Temporary ASP.net Files nor the applications/bin folder. this problem will also occur in any. net application if the Native DLL is not supported in the/bin folder with. EXE file or if the DLL is not in the Path Environment Variable.
 

  1. The directory from which the application loaded. in the case of ASP. net, this will resolve to % windir % \ Microsoft. net \ Framework \ v ###\ or % windir % \ system32 \ inetsrv for IIS 6.
  2. The current directory. in the case of ASP. net, this will resolve to % windir % \ System32 \ inetsrv for IIS 6. if using the built-in web server, this resolves to a path under C: \ Program Files \ Microsoft Visual Studio 8.
  3. The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. The directories that are listed in the PATH environment variable.

================
The options:
================

  1. Use DLLImport to load the dll using a relative or absolute path at runtime.
  2. Set the PATH Environment Variable so the ASP. net process can locate the C ++ DLL. you can set this property at runtime so that it only affects the process running your code. you can also set this globally in the System Properties (Environment Variables | PATH property ). setting this programmatically does not require a reboot and you can point the PATH to the/bin folder of the web app if you want to be able to do XCopy deployments of your ASP. net application. here are the steps to set the Path programmatically from ASP. net.

Option 2.a-If you want your Native C ++ DLL's loaded from the/bin of the ASP. Net application.

  1. Native C ++ DLL project
    1. Use al.exe to build a NativeWrapper for the Native C ++ DLL. this allows you to bring the Native C ++ DLL along with the DLL that is referencing it. you can add this in the Post Build Script of the Native C ++ DLL Project to automate this.

      Al.exe/link: "$ (TargetPath)"/out: "$ (TargetDir) $ (TargetName). NW. dll"/platform: x86

    2. Managed C ++ DLL Project
      1. Reference the NativeWrapper DLL-when you build this project, the native wrapper and Native C ++ DLL files are copied to the output directory along with the managed C ++ DLL
      2. Set Delay Load DLLs to the Native DLL. (C ++ Project Properties, Expand Linker, select Input, Delay Loaded DLLs)-This prevents the Native DLL from loading when the process starts, giving you a chance to set the PATH Environment variable. if you don't set this property, moci.net and its dependencies (I. e. the Native DLL) will be loaded before any of your ASP. net code can run and this will fail unless you have set the PATH environment variable on the machine level.
    3. ASP. Net Project
      1. Reference the managed C ++ DLL-The managed C ++ DLL, Native C ++ DLL, and NativeWrapper DLL are moved into the applications/bin folder.
      2. Add a Global. asax with the following code. (Right-click the Web Application, select Add, New Item, select Global Application Class ). you coshould also use an HTTPModule compiled into a DLL if you don't want people to be able to change your code. application_Start runs one time when the application loads and this code will set the PATH environment variable for the process to include the/bin directory of the application.

        Protected void Application_Start (object sender, EventArgs e ){
        String _ path = String. Concat (System. Environment. GetEnvironmentVariable ("PATH"), ";", System. AppDomain. CurrentDomain. RelativeSearchPath );
        System. Environment. SetEnvironmentVariable ("PATH", _ path, EnvironmentVariableTarget. Process );
        }

Option 2. B-If you want your Native C ++ DLLs to load from an installation path outside of the web site you can avoid the AL command. you wowould still need to set the Delay Load property on any Managed C ++ DLL that loads the Native C ++ DLL's as well as set the Environment Variable. if you choose to go this route, you can load the path to your Native C ++ DLL's dynamically from the web. config file at runtime:

  1. Native C ++ DLL Project-don't need to do anything in the Post Build Script
  2. Managed C ++ DLL Project
    1. Configure Delay Load DLL's and specify the Native C ++ DLL
  3. ASP. Net Project
    1. Reference the Managed C ++ DLL-only Managed C ++ DLL is in the/bin
    2. In web. config, add the following... Use a path where the Native C ++ DLL is located:
      <Deleetask>
      <Add key = "NativePath" value = "C: \ MyNativeDLLs"/>
      </AppSettings>
    3. In global. asax, add the following:

      Protected void Application_Start (object sender, EventArgs e ){
      String _ path = String. Concat (System. Environment. GetEnvironmentVariable ("PATH"), ";", ConfigurationSettings. deleettings ["NativePath"]);
      System. Environment. SetEnvironmentVariable ("PATH", _ path, EnvironmentVariableTarget. Process );
      }

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.