Cannot instantiate delphi written application.exe using IIS, MVC4, C# and COM - asp.net

My web application is a web interface for a desktop application called MyApplication.exe. My web application is written in C# (MVC4) that communicates with the MyApplication.exe (written in delphi) via COM-Objects.
When 16 clients invoke the web app via the browser, 16 MyApplication.exe instances will be created on the server:
My Problem: if client number 17 invokes the web application, I get the following exception in my eventlog:
"System Error. Code: 8. Not enough storage is available to process this command."
The process explorer indicates, that the worker process w3wp.exe consumes ~600 MB memory, but the machine has 4 GB RAM.
Note: The created instances will be saved in sessions (inProc).
Im am Using:
MVC4
ASP.NET CLR 4.0
IIS 8
Windows Server 2012 R2 (also occurs on Windows 8.1)
4GB RAM
I tried the following things:
Create instances locally via a VB-Script using COM-Objects. Result: I am able to create ~50 instances of MyApplication.exe with no problems.
Adapted the machine.config using the following entry:
processModel enable="true" memoryLimit="100"
Result: After restarting the worker process, the problem still occurs.

Depending on the user IIS is running under this could be a problem where the non-interactive desktop heap size is an issue. I've ran into this problem involving windows services.
When you run your test application most likely you are running under a different user. You can try adjusting the non-interactive desktop heap size in the registry to see if it resolves this issue:
Below is taken from KB 126962
To correct this problem, increase the size of the desktop heap: Run
Registry Editor (Regedt32.exe). From the HKEY_LOCAL_MACHINE subtree,
go to the following key: \System\CurrentControlSet\Control\Session
Manager\SubSystems Select the Windows value. From the Edit menu,
choose String. Increase the SharedSection parameter.
For Windows NT: SharedSection specifies the system and desktop heaps
using the following format: SharedSection=xxxx,yyyy Add ",256" or
",512" after the yyyy number.
For Windows 2000, Windows XP, and Windows Server 2003: SharedSection
uses the following format to specify the system and desktop heaps:
SharedSection=xxxx,yyyy,zzzz For 32-bit operating systems, increase
the yyyy value to "12288"; Increase the zzzz value to "1024". For
64-bit operating systems, increase the yyyy value to "20480"; Increase
the zzzz value to "1024".
Here is also a similar article for windows vista / 7 KB 947246

Related

Can't run exe from classic ASP script on IIS 7.5

I am attempting to upgrade an existing system from Windows XP Professional / IIS 5.1 to Windows 7 Ultimate (32-bit) / IIS 7.5. The original system ran a classic ASP website (only available to the localhost) that used 'ASPExec' to launch desktop applications on the local machine (.bat, .cmd, .exe, etc). Under Windows 7 Ultimate / IIS 7.5, the applications fail to launch from the ASP page.
As tests (The end goal is not to launch notepad), I have tried:
<%
Set Executor = Server.CreateObject("ASPExec.Execute")
Executor.Application = "notepad.exe"
Executor.ShowWindow = True
strResult = Executor.ExecuteWinApp
%>
I have also tried:
<%
Set wshell = CreateObject("WScript.Shell")
wshell.run "notepad.exe"
Set wshell = Nothing
%>
Both methods will cause notepad.exe to show in the Windows Process list, but fail to launch the application on the desktop. This is true for any .exe I try to run, and .bat or .cmd files simply fail to do anything.
With IIS 5.1, the original author of the ASP application used the "Allow Service to Interact with the Desktop" option on the "IIS Admin" service and "World Wide Web Publishing" service to make this work. All issues aside with allowing desktop interactive services, IIS 7 no longer uses the "IIS Admin" service, so this is not an option.
I am looking for either a workaround from the Windows/IIS side or another option in ASP that might acheive the same desired end result.
You won't be able to do this with Windows 7/IIS 7.5. The reason this worked was because you were running IIS5.1. Back in the days of IIS5.0/5.1 you had three different process models:
In Process (or Low Isolation mode) - where every site ran inside the inetinfo.exe process
Pooled Process - sites ran in an external surrogate process inside COM+
Out of Process (or High Isolation mode) - where each site runs inside it's own COM+ process
Most likely your IIS5.1 instance is configured to run in "In Process" mode and under the SYSTEM account. Because you can configure the IIS service to interact with the desktop, and because your Classic ASP script is being executed inside this process it is able to launch executables and they appear on the desktop.
In IIS7 life is different. Your code will run inside an application pool process which is spun up on demand. There is no way to configure pool processes (w3wp.exe) and allow them to interact with the desktop, even if running under the local system account.
Also unlike IIS6 you can't configure IIS7 to behave as if it's IIS5; IIS7 is a bottom up rewrite with a new architecture.
A possible workaround would be to write a simple WCF service with a HTTP endpoint that starts when the user logs on (hosted in a Windows app that hides or minimises itself to the notification area). You could then make calls to this service from your Classic ASP code using something like MSXML2.ServerXMLHttp and get the WCF service to launch these processes on your behalf.
This archived copy of chapter 29 of Keith Brown's "The .NET Developers Guide to Windows Security" explains the machinations involved in getting a service application to interact with the desktop:
The .NET Developers Guide to Windows Security - chapter 29 - How to Display a User Interface from a Daemon (source: archive.org)
Quote:
Option one is to get yourself into the interactive window station, and
option two is to have a process already in the interactive window
station display a UI for you.
An easy way to put a daemon in the interactive window station
(WinSta0) so it can have its own user interface is to package it as a
service that runs as SYSTEM and check the box that says, "Allow
service to interact with the desktop." This tells the SCM to launch
your service process in the SYSTEM logon session (WhatIsALogonSession)
and to attach your process to WinSta0 instead of the noninteractive
window station in which the SYSTEM daemons normally run,
Service-0x0-0x3e7$.
This is what you probably have already on your XP box. But as I explained, there is no way to configure worker processes to do this because you can't configure the "Allow service to interact with the desktop." flag, even though you can configure a pool to run as the local SYSTEM account. When the book was written this applied to Windows 2000/2003. With the advent of Windows Vista/2008 and onwards you have the added complication of UAC and getting past that as well.
What you should consider instead is option two: Use two processes
instead of just one. One process must be launched in the interactive
user's logon session and WinSta0. It should contain all the user
interface elements you need, and it can connect to your daemon process
using any secure form of interprocess communication you're comfortable
with
This is essentially what I've suggested.

How to run VS 2010 Local IIS in 32 bit mode

I have referenced some 32 bit and some 64 bit DLL in my ASP.NET MVC 3 project.
The projects compile but I get runtime errors.
It's because I am running the web project as 64 bit.
How do I "enable 32 bit" in my local IIS (just how I can do it in IIS 7.5 Pro)?
I am using .NET 4.0
The error I get is:
Retrieving the COM class factory for component with CLSID {A6775dfd2-1dfF-421C-A187-4D55F4DDFBFF} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
If you don't require the 64 bit component (not sure what is running there or if this can be excluded as you simply wanted to know how to run in 32 bit more)
http://learn.iis.net/page.aspx/201/32-bit-mode-worker-processes/
You can set it at the server level via:
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.enable32BitAppOnWin64:true
Or set your particular app pool (more recommended imho) you can try the following. Sorry the page this came from is no longer seemingly active and only googles caches is showing it now:
Force IIS to create a 32-bit app pool worker process
If your application is running as a web app, meaning it is running in
an IIS app pool worker process, you’ll want that worker process
(w3wp.exe) to be a 32-bit process. That can be specified in the
advanced settings of the app pool:
Select the app pool for your web app. Click Advanced Settings… under
Edit Application Pool on the right. Change the value of Enable 32-Bit
Applications under (General) to True.
Note that the word “Enable” in the setting doesn’t mean “allow” as in
“allow either 32- or 64-bit applications.” It actually means “force”
as in “force the worker process to run in 32-bit mode so that 32-bit
applications are supported.” This means that the app pool worker
process will always be launched as a 32-bit process when this setting
has a value of True. Setting it to False will launch a 64-bit app
pool worker process.
Note that when an app pool worker process is started, it shows up in
the Image Name column on the Processes tab in Task Manager as
w3wp.exe. When the Enable 32-Bit Applications setting has a value of
True, it will be listed as w3wp.exe *32.
IIS Express 7.5 (as used by Visual Studio 2010 if you install it) is 32 bit only:
http://learn.iis.net/page.aspx/1265/iis-75-express-readme/
To quote:
Both 32-bit and 64-bit systems are supported, however only a 32-bit build of IIS 7.5 Express exists.
So I can't imagine that your problems would be related to the usual 32bit / 64bit pool mode issues that can arise if all of your DLL's are 32bit.
However if you're trying to load a 64 bit COM DLL then this will fail; 64 binaries can't be loaded into a 32 bit process and vice versa.
Another gotcha is forgetting to tick the Use IIS Express checkbox when choosing which web server to debug with:
If you don't tick that checkbox then you'll run your site in a child application in the DefaultWebSite on the version of IIS7 that ships with Windows.
The DefaultWebSite runs in the DefaultAppPool, which in 64 bit versions of Windows runs as a 64 bit process. So you need to change the DefaultAppPool to run as 32 bit if you want to use this instead and consume 32 bit binaries.
You need to do this using IIS7's MMC snap-in or by running the appcmd.exe tool from the command line.
Set your compile target to x86 instead of AnyCPU or x64. Your dll will always run in 32-bit without you needing to mess with the IIS server settings.

Error Retrieving the COM class factory for component

I have a web service which loads a 32-bit COM component. I am running this web service with IIS server in my local machine.
When I load the the test page from Visual Studio it succeeds, on the other hand, while loading it using IIS, it display following error
Retrieving the COM class factory for component XXX failed due to the following error: 80070005.
I tried changing the webservice's platform to x86 from Any CPU but that dint help. I am running this on Windows Server 2008 R2 - 64 bit.
I had to enable the 32-bit Applications from the Application Pools settings.
Check permissions on that COM. It may be that when you're running tests from VS, you're running as you (admin), while the user running the website's app-pool is totally different. That user needs to be added read+execute (or, activate, whatever) permissions for "local".
Maybe also see this: Retrieving the COM class factory for component error while generating word document
Sarat, this cannot be right. The "Enable 32-bit Applications" under Application Pools Defaults is not for running 32-bit applications or to solve your problem. It is there to enforce running 32-bit applications UNDER 32-bit processes only, which is not necessary in this case. Most 32-bit applications run fine on 64-bit processes. That's why you can run MS Office 2010 (which is still a 32-bit application) on Windows 7 64-bit machines.
You must have other settings tried and true after nearly a full year answering the original problem.

ASP.NET application error when run in Win Server 2008 64-bit

May you help me, My ASP.NET application can't import excel file when migrating this application that run in Win Server 2003 32-bit to the Win server 2008 64-bit environment.
How to fix this bug? because in Win Server 2003 32-bit, it runs properly.
the error report that appear is:
*System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT: 0x800A03EC at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad) at Admin_ImportRisk.CreateTempTable() in C:\inetpub\wwwroot\ERMApproval\Administrator\ImportRisk.aspx.vb:line 66.*
The code in line 66 of my application is:
oBooks.Open(Server.MapPath("~/App_Data/Risk.xls"))
I have tried several scenarios:
Added Network Service user to the Microsoft Excel Application in DCOM configuration and set the identity of Application pool that in used to be same.
Added all many kind of user to the Microsoft Excel Application and My computer in security of DCOM configuration. And I have added many kind of user too in the application's folder.
Used corflags.exe to force 32-bit application to run in 64-bit environment
Used regsvr32.exe to register a Microsoft.Office.Interop.Excel.dll file to the windows 32-bit component services.
Used rundll32.exe to run the 32-bit Microsoft.Office.Interop.Excel.dll file in the 32-bit environment
But the result is still the same.
It will be a big honour if you can help me^^.
Best regards,
-imanuel-
The simple answer is to compile your project to target x86 only. This is a setting in the project settings. So the .net framework will only generate a 32 bit application at runtime, rather than defaulting to 64 bit. This is no different from setting corflags, however if you have multiple assemblies you ahve to make sure it's done for all of them. The application itself must target only 32 bit.
You're using a COM component that is 32 bit, and you can't do that in a 64 bit application, so force it to be 32 bit.
You can also force IIS to run it in the 32 bit context as documented here:
http://lostechies.com/gabrielschenker/2009/10/21/force-net-application-to-run-in-32bit-process-on-64bit-os/
Also, make sure the 64 bit version of Excel is not installed on the server, but rather the 32 bit version.

Cannot monitor iisprocess for leak in Debug Diagnostic Tool

I have an ASP.NET application that consumes a lot of memory. Therefore I want to use the Debug Diagnostic Tool to try to search if there might be a leak or something else.
In DebugDiag on the process tab I right click the w3wp.exe process and the only options I get are:
Terminate process
Copy
Only on some processes I get more options:
Monitor for leaks
Create full userdump
Why is this? Has it something to do with the identity of the worker process?
Can someone help me solve this so I can debug the worker process I am interested in?
Assuming you are are using DebugDiag 1.1. You need to use the correct version that matches the process architecture (there are 32bit and 64bit versions).
To check whether your application pool's worker process is 32bit or 64bit go to:
Control Panel -> Administrative Tools -> Internet Information Services (IIS) Manager
Don't open Internet Information Services (IIS) 6.0 Manager.
Open the Advanced Settings for your website (the link is on the Actions pane to the left). Note the Application Pool name then click Cancel.
Click on the Application Pools node on the left hand navigation tree pane and right click on the Application Pool noted above, select Advanced Settings.
If the application pool is 32bit then the setting Enable 32-bit Applications will be set to true, otherwise if false the pool will run in 64bit mode.
If the application pool is running in 64bit mode then you need to download and install the 64bit version of DebugDiag.
When you run 32 bit DebugDiag the column "32-Bit" on the processes tab will have "Yes" to indicate that a process is 32bit. Only these processes will have context menu options to 'Monitor For Leaks' and so on.
For more information see Tess Ferrandez's blog:
Capturing memory dumps for 32-bit processes on an x64 machine
If you can reproduce your suspected memory leak in 32bit mode then just switch the application pool to 32 bit and use the 32bit version of DebugDiag. Unfortunately both the 32bit and 64bit versions can't co-reside on the same machine.
Update:
DebugDiag 1.1 x64 only supports the
analysis features. There is a new
version in beta that does permit all
the functionality of the 32bit
version. Although not available
directly you can request a copy from
their support team, see the following
link for more info:
Debug Diag 1.2 (Beta)

Resources