Limiting the scope of a NamedPipeServerStream - c#

I would like to use NamedPipeServerStream to do some small IPC between instances of an app. However I only want to target the server if it is on the same Terminal Server Session as the client (If the app is run in a TS-environment).
An idea to achieve this would be to use the SID of the logon user and concat this with the Pipes name. Hover I think this will give problems if the user is loged on from two different locations and it also seems not very neat to me.
Is there a possiblity to give NamedPipeServerStream a scope in which it responds to calls and to set this scope so that the RDP-Session builds the border? Or has someone a good idea how to limit the scope/achieve the desired behaviour?

If you want to limit it to one session only you can create a named mutex within the local namespace to limit its visibility within your session. When a client wants to connect
it can create the same mutex and if it gets as last error code ERROR_ALREADY_EXISTS back it knows that within the current session a pipe server is.
You can get the current session number of your process via ProcessIdToSessionId so you can create a named pipe server with the session id in its name.
[DllImport("kernel32.dll",SetLastError=true)]
static extern int ProcessIdToSessionId(int pid, ref int session);
Addenum:
To get your current Session Id you can simply use Process.GetCurrentProcess().SessionId instead of the PInvoke signature defined above.

Related

Rest API restore last connection

I am working on a Rest API. So far I build a Webview where the user can make inputs and send them to the server. When the server receives the information it will start a program and do some calculations. The problem here is that opening the program needs a lot of time. So the user has to wait for +20 seconds.
The point is that the user will change data of the same object and send them back to the server. When the server gets these data again it has to open the program again so that the user has to wait for another 20 seconds.
The program is referenced as a library. I create an instance of it within the controller class. So each time the server gets a new request it will open an instance, pass the data to the program and return the result to the client.
My question here is: Is there a way to avoid opening an instance for each request and instead open an instance temporarily for each user?
Edit:
The program is written in VBA. It is a configurator which calculates whether an option works out or not. I will access it by creating an instance of it:
Configurator conf = new Configurator
After that you can either create a new position or recall an old one by passing an ID like this:
conf.ID = id;
This process needs a lot of time because the program is collecting a lot of data from a database.
So this is the process I want to skip and instead use the object I created before.
After that you can pass other data to the program/object like height etc.
You can use dependency injection engines like Autofac. Register your program instance onApplicationStart as a singleton instance. Then whenever you want an instance of the program.dll, autofac will give you the same instance according to your defined registration config which is singleton.

How to create an automated column in SQL Server?

IDE: Visual Studio, C# .net 4.0, Winforms application
Is there any way in SQL Server to implement a column in a table which can set itself automatically to 0 when it has not received any ACK (acknowledgement) signal from the application side?
The requirement is I want to keep a column which can keep track that Is application is open or it has been closed?
One way to implement is using the OnClose() event, i.e. on Close() I can change it's value to 0. but the problem is suppose application got hanged for some reason or Power is gone than the value in database will not be updated to zero.
So I want to create an automated column which can track this situation and make itself zero when the application is not sending any request or idle means closed.
please suggest how to handle this.
You can't do that. The only thing you can do is to save GETDATE() in a column in a table as the last activity time of the application and invoke the stored procedure from a high-priority thread every 10 seconds for example.
When you want to know if the application is alive or not, just check this value, if more than 10 seconds is passed since then, you app is gone.
UPDATE:
A more precise but complex approach would be to listen on a socket inside your application and then whenever you want to know if the application is alive, send a request from your sql script to PING the application. You should use CLR programming for this approach, but I think the first one will be practically enough.
Considering it will be a multiple instance scenario where multiple instances of the application can point to same database. You can try the following:
Create a separate table to maintain sessions. This table would contain three columns 1)Machine name or IP 2) Session Id (GUID) and 3) TimeStamp.
Whenever application starts create a new session id and make an entry into this table it means new session is started.
Keep on updating timestamp on every request based on session id.
Have a timeout configured somewhere in web.config or database which will come in handy later.
Now when application is exiting gracefully then delete the row from the table.
Now if application crashes the row won't be delete so next time when application starts you can check if the row already exists. Use machine name or IP to query to the table.
Use the timeout setting configured in (3) above to determine since how long the application is idle.

How to save clicking counter in c#

I build web-site and want to count clicks on some button. I create and try this class of counter:
public static class Counter
{
public static int counter = 0;
}
Every time I click on the button the counter is increament (counter++) ans I see it in my site, But, if I close the chrome and enter again to my site the counter starts from zero.
How can I save the counter? "Static" dont need to do that?
My bet is that it happens because the application space is flushed - it shouldn't reset just because you closed your browser window, thus abandoning the current session (if the session cookie isn't persistent, that is.)
Visual Studio may republish your files (if using a remote IIS) or just plainly restart a local IIS Express instance, depending on how you set your development environment; I do believe setting a specific content as Static would cause it to be available to all current sessions.
That said, you may want to keep it under the current session (using the Session object).
Optionally, if you want to persist information in between server restarts, you may try reading and writing to a local storage, such as a plaintext or XML file. You can find a very nice article about this on the following link:
http://www.codeproject.com/Articles/544839/Implement-ASP-NET-custom-XML-file-configuration
A more sophisticated version would use a local (or remote) database, for example.
Hope it works for you.
static fields are unique per-process. Depending on your application pool configuration, you could have 2, 20 or 100 copies of that.
They're also not thread safe. There are very, very few instances (pun) where a static member is appropriate.
Just off the top of my head, a particular "instance" of a static will disappear when:
The application pool is recycled. On IIS, this defaults to 20 minutes of inactivity.
The application process exits (you may have multiple processes running within your app pool). This happens as part of (1), but will also happen if, say, you're using the Visual Studio debug web server (Cassini), have your project configured to launch the site for debugging, and close the browser that was launched initially. (This happens because VS considers closing the browser that it launched equivalent to saying "I'm done playing. Back to coding now," or hitting the stop button.)
Another thread overwrites the value you've stored (google "race condition.")
You really, really should be storing this in a database. If you're building a website, you need a database anyway. ANYTHING related to application state should be stored in the database.
ALSO, this really, really shouldn't be happening server-side. Are you really performing a postback every time someone clicks anywhere on a page? If so, you have JavaScript in place to handle that, so just skip this insanity, have said script fire off an AJAX request, and have the target handler log it in the database.
Looks like your using a web site so presuming ASP.net. There are a number of ways to store the information. Database could be one or a persistent cookie could be the way to do it. See this article on how to create cookies: How do I set/unset cookie with jQuery?
You can try save it in session and then it will stay until the session is time out(20 minutes) if you want it to long time just write it to file in known location and when you close the web write the value to the file and when the web is up again take the vakue from the file.

Detect a remote desktop connection from a service at logon (W7/32)

I know (and it works) that in C#, this property tells me if the current session is a RDP one:
System.Windows.Forms.SystemInformation.TerminalServerSession
Now, I have a service that receives logon/logoff and lock/unlock events, and I need a way to tell this service if the session being started is rdp or local.
Problem: the service runs as SYSTEM user, and the property above always returns false (I think because SYSTEM is always considered a local connected user)
I've tried to search in the register for the Volatile Environment subkey to check if there is the subkey that identify the RDP Session Name: this works in lock/unlock handler, but in the logon handler the subkey doesn't exists yet (subkey is created after login completes).
Any idea about how to work around this problem?
While a wait for the key creation for a limited amount of time works, I would like a less "kludgy" way to do it.
You can detect whether a session is a local or remote session by calling WTSQuerySessionInformation with the WTSInfoClass parameter set to WTSClientProtocolType. If you'd prefer to avoid the P/Invokes, you can use the Cassia library: new TerminalServicesManager().GetLocalServer().GetSession(sessionId).ClientProtocolType.
Caveats: This won't help you when processing session logoff messages because you will not (reliably) be able to fetch information about the session, since it's in the process of being destroyed (but that seems relatively easy to work around). Also, the ClientProtocolType Cassia property mentioned above has not yet been released, but you can grab a trunk build from the build server by logging in as a guest and using the artifacts link.

Custom API requirement

We are currently working on an API for an existing system.
It basically wraps some web-requests as an easy-to-use library that 3rd party companies should be able to use with our product.
As part of the API, there is an event mechanism where the server can call back to the client via a constantly-running socket connection.
To minimize load on the server, we want to only have one connection per computer. Currently there is a socket open per process, and that could eventually cause load problems if you had multiple applications using the API.
So my question is: if we want to deploy our API as a single standalone assembly, what is the best way to fix our problem?
A couple options we thought of:
Write an out of process COM object (don't know if that works in .Net)
Include a second exe file that would be required for events, it would have to single-instance itself, and open a named pipe or something to communicate through multiple processes
Extract this exe file from an embedded resource and execute it
None of those really seem ideal.
Any better ideas?
Do you mean something like Net.TCP port sharing?
You could fix the client-side port while opening your socket, say 45534. Since one port can be opened by only one process, only one process at a time would be able to open socket connection to the server.
Well, there are many ways to solve this as expressed in all the answers and comments, but may be the simpler way you can use is just have global status store in a place accesible for all the users of the current machine (may be you might have various users logged-in on the machine) where you store WHO has the right to have this open. Something like a "lock" as is used to be called. That store can be a field in a local or intranet database, a simple file, or whatever. That way you don't need to build or distribute extra binaries.
When a client connects to your server you create a new thread to handle him (not a process). You can store his IP address in a static dictionary (shared between all threads).
Something like:
static Dictionary<string, TcpClient> clients = new Dictionary<string, TcpClient>();
//This method is executed in a thread
void ProcessRequest(TcpClient client)
{
string ip = null;
//TODO: get client IP address
lock (clients)
{
...
if (clients.ContainsKey(ip))
{
//TODO: Deny connection
return;
}
else
{
clients.Add(ip, client);
}
}
//TODO: Answer the client
}
//TODO: Delete client from list on disconnection
The best solution we've come up with is to create a windows service that opens up a named pipe to manage multiple client processes through one socket connection to the server.
Then our API will be able to detect if the service is running/installed and fall back to creating it's own connection for the client otherwise.
3rd parties can decide if they want to bundle the service with their product or not, but core applications from our system will have it installed.
I will mark this as the answer in a few days if no one has a better option. I was hoping there was a way to execute our assembly as a new process, but all roads to do this do not seem very reliable.

Categories

Resources