IIS Session isolation problem - c#

I am using ShDocVW.InternetExplorer class to spawn a new internet explorer object and to do some form filling stuffs(for some sharepoint works).It works fine in my own machine which has Windows 7 as the OS. But when I deployed the same thing in windows server 2003 machine, it does not pop up the internet explorer window. When I check the Task Manager, I could see a new iexplore process, but with Session ID = 0 (but session ID = 1 in windows 7). So, I see this is something regarding IIS Session isolation.So, is it possible to assign a ShDocVW.InternetExplorer instance to kind of a new System.Diagnostics.Process and achieve this task? Or can we start a new ShDocVW.InternetExplorer instance with session ID = 1?
thanks in advance.

I'm not very clear on what you are doing but if the app that spawns the ShDocVW.InternetExplorer process is an ASP.NET app then you won't see the window because IIS runs as a windows service and as such Windows Services use a different "desktop" than the desktop you're logged in as. So you'll never see any windows and Windows service application launches.
I think what you should do is create a GUI applications that instantiates your explorer window.

Basically the problem is that you are trying to do something through code, and since this will work on the server you will see a process getting spawned on the server... AND NOT on the client as you are assuming. It is working on your dev machine, since you would have been using FileSystem for your project and your project's pages are being served by cassini - Web Development Server which launches on your own machine.
The approach of filling out the form is wrong. You should be using POST request and read the values on the server for doing necessary processing of the data that has been posted.

Yap... I got the answer to the problem, In IIS we cannot spawn processes using Shell Execution with the default settings... If we need to do so, there are 2 workarounds that need to be set which can be found from here. And by the way, thanx very much for you guys' input and support which helps me to figure this out. cheers...

Related

Interacting with an open application via web link [duplicate]

A few years back I developed a Silverlight Component called from within an ASP.net web app, that uses PInvoke to access a USB (Serial COM port) on the client machine to allow for sending commands to some scanner hardware.
With the advent of Windows 10 and the inevitable demise of Silverlight I am looking for alternatives to accessing hardware on the client PC (This is all Intranet Web Application stuff where we have a lot of control over the implementation)
Currently I am looking at Registering an Application to a URI Scheme (Easy solution) as per this page:https://msdn.microsoft.com/library/aa767914(v=vs.85).aspx
OR alternatively maybe Javascript navigator.msLaunchUri (This seems to not be supported in Windows 7, which we need to still support)
Refer: https://connect.microsoft.com/IE/feedback/details/864863/documented-api-function-navigator-mslaunchuri-not-present-in-windows-7
The Registering of an Application to a URI Scheme works fine in Windows 7/8/8.1 but seems to have changed in Windows 10 - Does anyone know how I can implement this (Through C# code, registry, something) to allow this to work in Windows 10
I recently wanted to just this as well - and I found the answer so i'm posting it here for future reference and I couldn't find a working example in C# anywhere.
First of all your app needs requireAdministrator permissions. To do this, right click on the project in the Solution Explorer and click Add New Item, then select General and finally Application Manifest file if you don't already have one. In there, change the requestedExecutionLevel to requireAdministrator. Save.
I this is the first time you've done this, you'll need to restart Visual Studio as it probably isnt running under Admin privaleges.
Okay, so I wanted my app to create the registry key when it starts up, so in the constructor for my form I put in the following code, which creates the URL Protocol foo:// for a program called 'oggsplit.exe' (which I happened to have in my C: root so I just used that for testing)
RegistryKey key;
key = Registry.ClassesRoot.CreateSubKey("foo");
key.SetValue("", "URL: Foo Protocol");
key.SetValue("URL Protocol","");
key = key.CreateSubKey("shell");
key = key.CreateSubKey("open");
key = key.CreateSubKey("command");
key.SetValue("", "C:\\oggsplit.exe");
Once you've configured that, save and run the program. You'll get no feedback, and as long as you don't see any errors it should have worked correctly. Now, open your browser (no need to restart or anything) and go to the address foo://hello. This is what it looks like for me in Google Chrome:
It will then ask you if you want to open your application from the browser, click okay. Hey Presto, your app opens from the browser, you can now put a specilised link into your web page to open your app from the browser. This Page also documents how to pass arguments through to your program as well.
In win10 you can try to use URI handlers. There should be Package.appxmanifest file where you can list URIs that should launch your app.
Also, I found interesting the folowing article that describe web-to-app approach for various OS

How to pop up application using windows services c#

I want to pop up an application using windows services.
Right now the code that I am using is:
System.Diagnostics.Process.Start(#" ");
That code does not pop up the application when I start running the services.
You can not do that. User session interaction has been removed since Windows Vista. The process would be started in the session that the service runs in, which per definition is not desktop interactive.
What you can do is run windowless console-only tools.
Long story: Before Vista all services ran in the same session as the first logged in user ("session 0"). Since this is a security issue, this was changed in Vista, where a dedicated session ("session 0") is active from the start for services. The first user logs into session 1, the next user into session 2 etc.
Due to the separation of these sessions it is no longer possible to create desktop interactive services - there is no desktop session for services.
This also means you can not display message boxes or run desktop interactive tools in session 0 - there's nobody who can see them.
Is that the exact code that you're using?
If so you're not actually giving the process anything to start, just an empty string. You need to pass it the name of the executable.
For example:
System.Diagnostics.Process.Start(#"C:\Windows\System32\notepad.exe");
If this is not the exact code, please post modify the question with the exact code.

C# process.start not working on iis

I'm trying to run an exe with parameters from a web application.
I'm using Process.start() but it does not seem to run on iis!
It works fine when running from iis express. I'm publishing the application to my local iis as a test but it does nothing.
I've tried setting the iis admin service to enable interactions with the desktop and ive told iis to connect as my user credentials and set the application pool to use the same user credentials but still nothing works!
is there anything else someone can advise to get this working!
Cheers.
UPDATE
I got iis to run the process by setting the application pool identity to local system and double checking the credentials for the site.
But as expected the applications do not interact with the desktop, so creating a file from command line is simple, but running an application with parameters do not have the application open.
At the moment iis admin service has interact with desktop checked and is using the local system account.
Ok so this isn't really an answer but in the end I got process.start to work by setting the application pool identity to local system.
But as expected the commands do not interact with the desktop, but this was enough for what my application needs to do.
Sorry for the poor answer.

How to get Currently logged user's session ID?

I'm running a process from inside a windows service using
ProcessStartInfo processStartInfo = new ....
Process.Start(processStartInfo);
The problem is, if I run service under local system account, it runs alright, but it doesn't show the programs' window.
I've tried to put user credentials in service properties, but then 'Allow service to interact with desktop' checkbox becomes disable.
I really need to run the app calling it from service, and I really need to see the app's window.
Help me please.
UPD. Well, you use overloaded version of Process.Start what takes username, password and domain - it will pull the program to the desktop. But now it starts the app under one credentials but shows that on a different user's desktop. How come?
UPD2: I have an idea! I can use psexec.exe from Sysinternals Suite. But the problem is I need to start that thing silently "as administrator". And I don't know how.
I mean even if you're already have admin rights, sometimes you have to manually say "run as administrator", confirm UAC and only after that you're ready to go. I don't know how silently run something without bringing UAC thing....
UPD3: Dear Lord. I've got that thing! Finally.
Ok. In the beginning the problem was indeed in session 0 isolation thing. So I needed to build a middle app that can be started from the service and then, that app in its turn suppose to start my application through RPC and bring it to a desktop. Instead of building middle layer app I decided to use psexec tool (anyway it works exactly the way I need - through RPC).
And when I tried to use that tool under LOCAL SYSTEM account it didn't work for some reason. And then I realized - the reason is damn EULA popup dialog that MS put in every single pstool, and it was impossible to click the button to confirm dialog under local system account.
So the solution is to create a key in the registry HKU.DEFAULT\Software\Sysinternals\PsExec with DWORD value EulaAccepted = 1
Hooray, now it works!
BUT! Now I need to bring the program to the currently logged user's screen. To do that I'm gonna need the session id!
So the question is: How to get currently logged user's session id? And what happens if there's no one logged yet? What session id that would be?
UPD4: That's it! I got that one!
[DllImport("Kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId")]
public static extern int WTSGetActiveConsoleSessionId();
Thank you guys!
You can get the active console session id using WTSGetActiveConsoleSessionId (from the terminal services API). You can only use it for WinXP/Win2K3 or higher, but that should be fine, as you can hard code 0 for the session id on Win2K or earlier. Here is the PInvoke signature for it:
[DllImport("Kernel32.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.U4)]
public static extern int WTSGetActiveConsoleSessionId ( );
As far as launching a process in the user's session, you can refer to the answer I gave here. It basically involves callling four API's; WTSGEtConsoleSessionId, WTSQueryUserToken, DuplicateTokenEx, then CreateProcessAsUser, and it will work on any machine running WinXP/Win2K3 or higher.
One solution would be to have a third process act as an intermediary, and tell it to launch apps via RPC/Named pipes.
Processes:
Windows service
Intermediary application
The app you want to run
The shim creates a communication endpoint (named pipe, WCF endpoint) and listens on it. When it gets a message to go ahead, it launches the app you want to run.
Then, when the Windows service wants to launch an app, it finds and opens the endpoint (named pipe, WCF endpoint), and sends the message to launch the app. Then the intermediary application takes care of the process launching business, and doesn't have any of the limitations that the Windows service has.
Make this intermediary process start with logon, and you're good to go.
This is similar to how the Microsoft test agent/controller work when you need to run tests that interact with the desktop.
This can be done without an intermediate process, but it requires more than 500 lines of code to do. Basically, you want to launch your second process as the current logged on user. For Vista/7, this user will have their own winlogon process, while for XP, they will have an explorer process. You need to get the primary token, environment block, security attributes, and thread security attributes of that running process then call the Windows API function CreateProcessAsUser with all that information, making sure you select the correct window station as well (usually "WinSta0\Default"). This is all doable, but you might have a better time with the other suggestion of a second process and IPC.
If you are trying this on anything newer than WindowsXP this will not work. This is because of a new feature introduced in Vista / Windows 7 called Session 0 isolation. http://msdn.microsoft.com/en-us/library/bb756986.aspx You will not be able to get a app launched by a service to show up on the users desktop.

Check if IIS Application is running without causing it to run

I am writing a web monitor app that gives information about all app pools / apps on my IIS server. I am looking for a way in C# to programmatically check if an IIS application is running without causing it to run if it is not.
Here is what I have found...
application is running, there are one or more sessions active.
all sessions dropped off...application still "running", app pool worker process is running.
At some point determined by IIS, the Application_End is finally executed...however, the app pool worker process is still running.
After 20 minutes, the app pool worker process finally shuts down due to inactivity.
It is between #3 and #4 that I am having trouble. The application has ended, but if I try to send an Http Request to the app, it will automatically start up. I am looking for a way to programmatically determine if the application has ended (while the worker process is still active awaiting shutdown) without restarting the Application.
I can try to provide more details if you are unsure what I am talking about.
Regards,
Jeremy
I found this on MSDN
public bool CheckIISRunning()
{
ServiceController controller = new ServiceController("W3SVC");
return controller.Status == ServiceControllerStatus.Running;
}
For this to work you need to have
System.ServiceProcess added as a reference.
Microsoft has created a VBScript file to identify the IIS Application Pools (by Process Id). If you search "iisapp.vbs" on google it should point you in the right direction.
Note: I'm not 100% sure that it will work with Windows Server 2008, but does work with 2003.
In IIS7 you can use appcmd apppool /? to see what possibilities are available.

Categories

Resources