Run ActiveXObject COM component that creates dialogs under IIS in Asp.NET - asp.net

I have a ASP.NET MVC app, hosted on IIS on a dedicated server. At some point I need to create a com activex component. I use Interaction.CreateObject from Microsoft.VisualBasic.Interaction for this.
The issue is that this activex component shows some dialogs when starting and waits until they are closed before actually registering as COM component.
I wrote some simple code that closes the windows via Windows API using FindWindowEx etc. and it works on a dev machine when hosted under VS, but it looks like on IIS these windows are never shown even in Windows API and ActiveX component just freezes waiting for dialogs to close that never exist.
I tried:
Using Process.Start and then Interaction.GetObject instead of Interaction.CreateObject
Setting AppPool in IIS to run from a real user identity
Setting Load User Profile to True in IIS
Using https://github.com/mj1856/SimpleImpersonation library to run the code as a user
I also looked in dcomcnfg (and this is my best bet on what I need to do). I thought I need to find my COM component there, and set Identity to specific user - but for some reason the ActiveX COM component I'm running does not exist there. I see "cannot register COM component" in Event Viewer if the component run crashes by timeout (because it waits for dialogs before registering as COM), - so I know AppID, but it does not exist in the list in dcomcnfg. Maybe because the ActiveX is exe, not ocx?
I know IIS is not supposed to run anything with windows, and it of course cannot show them, but I was at least expecting to see them with Windows API and being able to close them, especially given that the component waits for them to be closed, so they exist somewhere. I think I'm missing some clever setup on the server.

Related

Debugging a VB6 ActiveX DLL called via VBScript in a Classic ASP Application

Whelp, I avoided it as long as possible, but the time has finally come to make some changes to some ancient VB6 code. I'm a recent college grad so I was hoping to stay away from this code that is almost as old as I am.
The DLL is compiled in a local installation of VB6 and deployed via Component Services. That component is then called by VBScript in a Classic ASP application running on a windows 2003 Server.
I've tried just about everything to debug this code using the VB6 debugger, but I can't get it to work. I've compiled the DLL to the same location that Component Services has it deployed to (a random folder on a non-system drive), and set binary compatibility to that same DLL. Each class file has instancing set to MultiUse and MTSTransactionMode set to '1 - NoTransactions.' The component works fine until I attach the debugger, then I get 'ActiveX component can't create object' when trying to instantiate the object. If I detach the debugger, it works again.
I noticed that in Component Services when I attach the debugger, the DLL location changes to C:\Program Files\Microsoft Visual Studio\VB98\VB6DEBUG.DLL, which I assume is just VB6 intercepting calls to the component. When I detach the debugger, it changes back. I should also note that the component is configured to use a specific user identity separate from my logged-in user account, however everyone has been granted access to the component via a user role. The component activation type is also 'Server Application,' however setting it to 'Library Activate' doesn't seem to make a difference.
I've also tried using the VC++6 IDE, and VS2010, but had no luck. I was able to debug the dllhost.exe in VS2010 and was able to hit some breakpoints, but the symbols weren't loaded properly. I tried compiling the DLL with debugging symbols and loading those to the VS2010 environment via the Debug settings menu, however that didn't resolve the issue.
I also didn't find the component services JIT Debugger to be very useful. I'd much prefer to just be able to debug in VB6.
What amazes me most is that this code is thousands of lines and has been maintained without the use of any debugger whatsoever. My young, spoiled self isn't ready to accept that this code can't be debugged.

asp.net references a DLL that runs thread

I am new to ASP.NET and I need to develop an application that communicate with a RFID reader.
In order to do that, I have a DLL project which runs a thread that manages the communication with the reader, while a I have another ASP.NET project which manages the user interface.
Those two projects live in the same solution, so the ASP.NET project references DLL project.
At the beginning of the application, my "Global.asax" file initializes the reader (DLL project), running the thread it has inside, and registering some events such as "CardInside" the DLL fires, when a card is inside the reader.
My doubt is if this thread is really running because it does not do anything. I have placed more than one breakpoints in order to see if that part is being run, but nothing stops there.
I have read something about an issue regarding threads an asp.net, but since this thread is not used in a http request:
-is there any problem running a thread in ISS server at the same time as web page?
-Does an aspx.cs file register events fired by another object normally?As if it were not a web application?
-I am using visual studio 2015, could I use DEBUG object to show messages amongst my DLL lines of code?
Thanks a lot.
Yes, there are issues with running threads inside of IIS that are not requests. When no requests have come in IIS will tear down the AppDomain and that will Thread.Abort() the thread you are running your background work in.
You will need to move your code out of IIS and change it in to a actual windows service if you want it running all the time. You then can have your IIS portion talk to the windows service (or vice-versa) to process whatever the web component is.

IIS open file on Active User's Desktop

Here is situation:
I have a large collection of videos on a computer, and it will be hooked up to my TV. I would like to make an app to open my videos on my computer from my mobile device (Yes, I know it exists, I am just working on it for fun)
So I have setup a web service, and an app to consume said webservice. The webservice gathers a list of folders/files, and sends them to my device as well as can take in a file path and open it with the default program using System.Diagnostics.Process.Start(path)
When I am using IISExpress, it works fine, but I would like to use IIS. When I use IIS, I open the video file and hear it playing in the background, but it doesn't show up on the monitor. VLC appears in the task manager, and when I kill it, the sound stops.
I'm assuming the issue is the identity under which the app pool is being run, but when I tried to change the identity, it didn't make any difference. If it helps, I am running Windows 8. Does anybody have any thoughts on how I can make the app pool run under my identity, or open the process on the desktop of the active user, rather than open it under the app pool's name?
This is something rather difficult to implement due to Windows session isolation. IIS as well as its worker processes are in session 0, while your logon session is usually > 0. Via native Win32 API it is possible for something in session 0 to launch executable in other sessions, but I don't think it is worth the while.
Please use IIS Express, as it runs in your logon session directly, and don't need to cross the session boundary at all.
With regards to the Process.Start() problem I think in addition to changing the identity of the application pool you also need to go to Services under Administrative Tools and check the box "Allow the service to interact with desktop" under the Log On tab for the World Wide Web Publishing service. I think this has already been addressed in the following question: System.Diagnostics.Process.Start not work from an IIS
Now, if I had to put an app like this together I would try I slightly different approach: in addition to what you have already, I would build a small desktop app that autostarts and sits in the system tray when you log onto your desktop. It will listen for messages from the asp.net application on named pipes or tcp or something similar and start the processes from within the correct user context. That seems a more stable approach, which will also allow you to separate the web server from the desktop where the videos will be played.

Run console application (.exe) from within ASP.NET application (IIS 7,5)

I have an ASP.NET application on Windows 2008 R2 (.NET Framework 4.0, IIS 7.5) and I want to run a console application when I click a button on a web page. Here is the code:
protected void btnUpdate_Click(object sender, EventArgs e)
{
string fileLocation = #"D:\DTDocs\App_Code\LoadDTDocsXML.exe";
ProcessStartInfo oStartInfo = new ProcessStartInfo();
oStartInfo.FileName = fileLocation;
oStartInfo.UseShellExecute = false;
Process.Start(oStartInfo);
}
When I run ASP.NET application from within Visual Studio 2010 (with its internal IIS), the console application run Ok. But when I run the ASP.NET application outside the VS 2010, I haven't an error but the console application doesn't make his job (it must create an xml file on the disk).
I think the problem is the configuration of IIS 7.5, I don't know exact to which account I must give access rights to the folders involved in my console application.
In IIS 7.5, I set Physical Path Credential for Specific User = my windows account, but that not solve the problem.
Thanks.
Just to add to the other 2 answers - Do you really need to run an exe from your webserver?
I've had to do it in the past and it's almost always the option of last resort - It weakens your security considerably (Now all someone has to do to run executables on your system is find a single flaw in your code) and has a whole host of other problems (the webserver isn't "logged on" to the server so it doesn't have a desktop, impersonation is a real pain in the a$$ to get working properly (assuming you're going to run the executable with different permissions to the webserver), etc.
If there's any other way to accomplish your goal, it'll almost certainly be simpler.
An option we went for was to have a new app with a WCF endpoint that the webserver can communicate with. So, when someone pushes the button, the WS call's our app via WCF and tells it to run various commands. This way, you've got:
Clean seperation between web and console code.
A dodgy console app won't take down the webserver & vice-versa
If the console app is long-running, this allows you to stagger your releases for website/console app so that you don't kill the app mid-execution just because you need up upodate some CSS and publish.
Huge security benefits - web server can't run executables even if compromised.
The WCF app will be able to closely examine requests to decide if they're valid before execution.
Be aware that however you do it, if someone malicious works out what's going on and can kick off the process, they could probably DoS you with almost zero effort - Make sure that this method is locked down TIGHT.
Edit: having read your comments above, I think you're hitting the "desktop" issue. When launching an executable from the server, the app will never be visible to the logged on user as the logged on user's desktop isn't accessible from IIS and vice-versa. This is very similar to the issue of having a GUI on a windows service.
This may also be of interest.
the first problem I see is security/file access. when running from within VS the server and client are the same machine under your credentials. when run in testing/production environment the server and client are physically different machines and IIS will run the website under restricted permissions. therefore there is a very good chance that IIS cannot access the file at D:... because of security.
the next issue is running a console app from the website. console is another form of UI just like html and a WPF. personally I wouldn't execute the console from the web (unless there was no other choice). I would integrate the API into the web application. 2 UIs sharing the same logic.
ASP.NET Dev Server runs under credentials of current user (it's you).
IIS 7.5 runs ASP.NET applications under user specified in application pool settings -- usually ApplicationPoolIdentity (to which you can refer as user "IIS AppPool\[ApplicationPoolName]", when configuring file permissions). You can also change it to "Network Service" (Default value in IIS 7.0).
Please check, which identity is configured for your application pool, and give this user required permissions.

Launch process on server from asp.net codebehind and have it visible on server desktop

I have a program running on my desktop machine that makes a WCF service available. This is a regular Windows Forms application that I run when logged in as a normal user.
I put the WCF interface in so that I could see the status of the program from an external web page. This works great, I can see the status of the running program and even change things as I see fit.
The only thing I can't do is start the program. If I go to the web page and the program is not running, I'd like to be able to start it. A simple Process.Start(programEXE) doesn't suffice because while the program starts, it is not on the desktop and I can't see it, though it does show up in Task Manager.
I tried creating credentials and launching the program with those credentials, but it exits with a very vague "Program failed to start" error, or starts with my credentials but still doesn't show up on the desktop. In the latter case, I see it in Task Manager under my name, but don't see the actual program.
So, How do I start a program on the server, visible on the desktop of the logged-in user (There's only one user and that user is always logged in)?
Also, what are some things that I can do to ensure that this doesn't become a security hole? One thought I had was to run the launcher.aspx in its own virtual directory, under a userid that only has read permissions to the one directory where program.exe is located, and has no other read or write permissions. Any other suggestions?
Finally, just to be clear: I am not trying to launch anything on the user's computer. Clicking on the "launch program" link should launch a program on the web server and not on the client machine, and that program should be visible to the logged-in user on the server.
I'm almost positive that you can't do that. Your IIS runs as service and does not have a specific desktop environment associated with it. What you're trying to do doesn't really work in the web/server environment.
I'd recommend that you change your win form app to a windows service and then you'd be able to start/stop it via web site. If you enable "interact with desktop" with the windows service then I think you'd be able to have a form.Show() bring the app to the current user's desktop environment.
If you are the only person that needs to run the winform app, then why not just start the app yourself? You state that it'll probably never be used by any computer other than your own computer, so it seems like a complicated method of accessing a local web site to start a local winform app when you could just start the winform app via shortcut.

Resources