Automatic call to restart a local window service, Privileges issue - c#

I've got a problem with setting the Admin privileges in a propper way; I have already tried ServiceController & ServiceControllerPermission, and it failed, cannot find any solution on the internet which will solve my problem. Code written below:
public class Restarter
{
public string Run(string serviceName)
{
var ctlPrms = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, serviceName);
ctlPrms.Assert();
var srvCtl = new ServiceController(serviceName, Environment.MachineName);
srvCtl.Refresh();
var msg = $"At the beginning, Service: {srvCtl.DisplayName} has status of: {srvCtl.Status}!\n";
if (srvCtl.Status.Equals(ServiceControllerStatus.Running))
{
msg = msg + "Attempting to stop running service\n";
srvCtl.Stop();
srvCtl.WaitForStatus(ServiceControllerStatus.Stopped);
}
else
{
msg = msg + "Attempting to start the service\n";
srvCtl.Start();
srvCtl.WaitForStatus(ServiceControllerStatus.Running);
}
msg = msg + $"At the end, Service: {srvCtl.DisplayName} has status of: {srvCtl.Status}!";
return msg;
}
}
I will be more than gratefull for help with that, I'm already pulling my hair out because of it

Related

how to get information from user on alexa skill launch

I've got an Alexa app that on first launch looks for the user's id in a dynamoDB. If it isn't there I'd like it to ask the user for their ip address.
I have an intent that can collect the IP but I was wondering if I could trigger the intent from the launch request?
private SkillResponse LaunchRequestHandler(SkillRequest input, ILambdaContext context)
{
// Initialise response
var skillResponse = new SkillResponse
{
Version = "1.0",
Response = new ResponseBody()
};
// Output speech
SsmlOutputSpeech ssmlResponse = new SsmlOutputSpeech();
try
{
try
{
var strUserId = input.Session.User.UserId;
var request = new GetItemRequest
{
TableName = tableName,
Key = new Dictionary<string, AttributeValue>() { { "strUserId", new AttributeValue { S = strUserId } } },
};
var response = client.GetItemAsync(request);
// Check the response.
var result = response.Result;
var attributeMap = result.Item;
if (result.Item.Count() < 1)
{
ssmlResponse.Ssml = "<speak></speak>";
// Trigger intent to get IP address and port number.
}
else
{
ssmlResponse.Ssml = "<speak>Hi there. I'm not Cortana.</speak>";
// Give command guidance prompt.
}
}
catch (AmazonDynamoDBException e) { ssmlResponse.Ssml = "<speak>" + e.InnerException.Message + "</speak>"; }
catch (AmazonServiceException e) { ssmlResponse.Ssml = "<speak>" + e.Message + "</speak>"; }
catch (Exception e) { ssmlResponse.Ssml = "<speak>" + e.Message + "</speak>"; }
skillResponse.Response.OutputSpeech = ssmlResponse;
skillResponse.Response.ShouldEndSession = true;
}
catch
{
//ssmlResponse.Ssml = "<speak><audio src='/samples/ImSorryDave'/></speak>";
ssmlResponse.Ssml = "<speak>I'm sorry Dave. I'm afraid I can't do that.</speak>";
skillResponse.Response.OutputSpeech = ssmlResponse;
}
skillResponse.Response.ShouldEndSession = true;
return skillResponse;
}
Two options I can think of:
Have you tried just asking for the IP address? <speak> Hi there. What is your IP address?</speak> If you make sure your IP address intent has examples of how you might expect a user to respond to that question, that intent should be the triggered and sent to your skill to process.
Also look into how Alexa can handle some of the dialog management for you with intent chaining. The example there sounds very similar to your use case.

EasyNetQ/RabbitMQ client not getting response in IIS Web Application

I'm using EasyNetQ/RabbitMQ to connect a web application running in IIS to a Windows service. However, I don't seem to get the request/response to work. I pretty sure it's not a code problem but I'm running out of ideas where to look at next.
This is a test console application that works just perfectly:
static void Main()
{
var stopHandle = new ManualResetEventSlim();
var producer = new Thread(() =>
{
string cs = "host=localhost;virtualHost=/;username=demo;password=y4xHEyq3nQOd;timeout=120;persistentMessages=false;prefetchcount=1";
var bus = RabbitHutch.CreateBus(cs, x => x.Register<IEasyNetQLogger>(s => new EasyNetQ.Loggers.ConsoleLogger()));
while (!stopHandle.IsSet)
{
try
{
var result = bus.Request<AutomationRequest, AutomationResponse>(new AutomationRequest
{
taskId = "140061381555",
arguments = "type=pdf",
issueId = 97630548355,
});
Console.WriteLine("Result: " + result.status + ", " + result.status + ", " + result.downloadUrl);
}
catch (Exception)
{
Console.WriteLine("Failed");
}
if (!stopHandle.IsSet) Thread.Sleep(1000);
}
bus.Dispose();
});
producer.Start();
Console.ReadLine();
stopHandle.Set();
producer.Join();
}
}
This on the other hand is the same test code but as a web application:
namespace WebApplication2
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
string cs = "host=localhost;virtualHost=/;username=demo;password=y4xHEyq3nQOd;timeout=120;persistentMessages=false;prefetchcount=1";
IBus bus = RabbitHutch.CreateBus(cs, x => x.Register<IEasyNetQLogger>(s => new EasyNetQ.Loggers.ConsoleLogger()));
try
{
var result = bus.Request<AutomationRequest, AutomationResponse>(new AutomationRequest
{
taskId = "140061381555",
arguments = "type=pdf",
issueId = 97630548355,
});
Console.WriteLine("Result: " + result.status + ", " + result.status + ", " + result.downloadUrl);
}
catch (Exception)
{
Console.WriteLine("Failed");
}
bus.Dispose();
}
}
}
Web application sends the message just fine, at queued and it's processed on the back end. Back-end provides the response with the correct correlationID and queues it. However, for some reason unknown to me, the Web application never gets the response.
The Web application eventually gets a timeout. However, the length of the timeout is not the problems, as the getting the response into the queue takes just about two seconds, and changing the timeout to two minutes on both sides does not make any difference.
Does somebody have a ready solution what to fix? Or any ideas where to look? I have googled everything I could figure out about EasyNetQ or RabbitMQ but I didn't even find anybody having reported about similar problems.
--karri

Connecting to the MQ Server using CCDT

I'm trying to connect to the MQ using the information present in the CCDT file. I can currently connect to the MQ using all the details, and get and put messages from and to the queue.
After extensive googling, I've been unable to find any sample code which allows me to connect using the CCDT file.
One of my colleagues forwarded me his JMS connection code, but I've been unable to port it to C#.
The JAVA code is as follows -
public class MQTest {
public static void main(String[] args) {
MQQueueManager queueManager = null;
URL ccdtFileUrl = null;
MQMessage mqMessage = null;
//MQPutMessageOptions myPMO = null
try {
String QM = "IB9QMGR";
String QUEUE1 = "TEST";
System.out.println("Starting MQClient Put Program: ");
ccdtFileUrl = new URL("file:///D:/AMQCLCHL.TAB") ;
ccdtFileUrl.openConnection();
queueManager = new MQQueueManager("SDCQMGR.T1", ccdtFileUrl);
System.out.println("Connected to QMGR ");
int openOptions = MQC.MQOO_OUTPUT;
MQQueue InQueue = queueManager.accessQueue(QUEUE1,openOptions,null,null,null);
MQMessage inMessage = new MQMessage();
inMessage.writeString("###Testing####");
InQueue.put(inMessage);
System.out.println("Message Id is :" + inMessage.messageId);
System.out.println(inMessage.toString());
InQueue.close();
queueManager.disconnect() ;
}
catch(MQException ex){
System.out.println("MQ Error - Reason code :" + ex.reasonCode);
}
catch (Exception e){
System.out.println("Error : " + e);
}
}
}
Instead of URL, I used the URI (in C#) to set file location. (This may be wrongly used. Not sure what else to use though.)
Uri ccdtFileUrl = new Uri("file:///D:/AMQCLCHL.TAB") ;
but I can't use openConnection() on a URI. Also,
queueManager = new MQQueueManager("SDCQMGR.T1",ccdtFileUrl);
gives an argument overload exception. As URI is not supported in C#.
I've tried looking up samples but I've found some JMS samples and thats it. Looking for some sample code to connect in C#.
You will need to set MQCHLLIB and MQCHLTAB environment variables to use CCDT. You can set these two variables either from command prompt,app.config or code in the application itself.
Following example demonstrates usage of CCDT:
MQQueueManager qm = null;
System.Environment.SetEnvironmentVariable("MQCHLLIB", "C:\\ProgramData\\IBM\\MQ\\qmgrs\\QM1\\#ipcc");
System.Environment.SetEnvironmentVariable("MQCHLTAB", "AMQCLCHL.TAB");
try
{
**Hashtable props = new Hashtable();
props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
qm = new MQQueueManager("QM1",props);**
MQQueue queue1 = qm.AccessQueue("SYSTEM.DEFAULT.LOCAL.QUEUE", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING);
MQMessage msg = new MQMessage();
msg.WriteUTF("Hello this message is from .net client");
queue1.Put(msg);
queue1.Close();
qm.Disconnect();
}
catch (Exception ex)
{
Console.Write(ex);
}

.net remoting problem with chat server

I have a problem with my chat server implementation and I couldn't figure out why it doesn't work as intended.
The client could send messages to the server, but the server only sends the messages to itself instead of the client.
E.g. the client connects to the server, then types "hello" into the chat. The server successfully gets the message but then posts the message to its own console instead of sending it to the connected clients.
Well... maybe I have missed something as I'm very new to .Net remoting. Maybe someone could help me figure out what the problem is. Any help is appreciated!
The code:
I have a small interface for the chat implementation on the server
public class ChatService : MarshalByRefObject, IService
{
private Dictionary<string, IClient> m_ConnectedClients = new Dictionary<string, IClient>();
private static ChatService _Chat;
private ChatService()
{
Console.WriteLine("chat service created");
_Chat = this;
}
public bool Login(IClient user)
{
Console.WriteLine("logging in: " + user.GetIp());
if (!m_ConnectedClients.ContainsKey(user.GetIp()))
{
m_ConnectedClients.Add(user.GetIp(), user);
PostMessage(user.GetIp(), user.GetUserName() + " has entered chat");
return true;
}
return false;
}
public bool Logoff(string ip)
{
Console.WriteLine("logging off: " + ip);
IClient user;
if (m_ConnectedClients.TryGetValue(ip, out user))
{
PostMessage(ip, user + " has left chat");
m_ConnectedClients.Remove(ip);
return true;
}
return false;
}
public bool PostMessage(string ip, string text)
{
Console.WriteLine("posting message: " + text + " to: " + m_ConnectedClients.Values.Count);
foreach (var chatter in m_ConnectedClients.Values)
{
Console.WriteLine(chatter.GetUserName() + " : " + chatter.GetIp());
chatter.SendText(text);
}
return true;
}
}
My Server implements the chatservice as singleton:
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ChatService), "chatservice", WellKnownObjectMode.Singleton);
My client is also simply straight forward:
[Serializable]
public class Chat_Client : IClient
{
private string m_IpAdresse;
private string m_UserName = "Jonny";
private string m_Input;
public Chat_Client(string ip, string username)
{
m_IpAdresse = ip;
m_UserName = username;
}
public bool HandleInput(string input)
{
if (input.Equals("exit"))
{
Client.m_ChatService.Logoff(m_IpAdresse);
return false;
}
m_Input = input;
Thread sendThread = new Thread(new ThreadStart(SendPostMessage));
sendThread.Start();
//Console.WriteLine("post message");
return true;
}
private void SendPostMessage()
{
Client.m_ChatService.PostMessage(m_IpAdresse, m_Input);
Thread thisThread = Thread.CurrentThread;
thisThread.Interrupt();
thisThread.Abort();
}
public void SendText(string text)
{
Console.WriteLine("send text got: " + text);
Console.WriteLine(text);
}
The main client connects to the server via:
public void Connect()
{
try
{
TcpChannel channel = new TcpChannel(0);
ChannelServices.RegisterChannel(channel, false);
m_ChatService = (IService)Activator.GetObject(typeof(IService), "tcp://" + hostname + ":9898/Host/chatservice");
System.Net.IPHostEntry hostInfo = Dns.GetHostEntry(Dns.GetHostName());
m_IpAdresse = hostInfo.AddressList[0].ToString();
Chat_Client client = new Chat_Client(m_IpAdresse, m_UserName);
Console.WriteLine("Response from Server: " + m_ChatService.Login(client));
string input = "";
while (m_Running)
{
input = Console.ReadLine();
m_Running = client.HandleInput(input);
}
}
}
#John: No, I wasn't aware of that. Thanks for the info, I'll look into it.
#Felipe: hostname is the dns name of the server I want to connect to.
I found a workaround to make this work. I added an additional TcpListener to the client to which the server connects when the client logs in. Over this second channel I transmit the chat messages back.
However I couldn't understand why the old solution does not work :<
Thanks for the hints guys.
The best thing to do with .NET remoting is to abandon it for WCF. If you read all the best practices for scalability, the way you end up using it is extremely compatible with the Web Services model, and web services is far easier to work with.
Remoting is technically fascinating and forms the basis of reflection, but falls apart once slow, unreliable connections are involved - and all connections are slow and unreliable compared to in-process messaging.

Modify the code to perform operation on remote servers

I wrote the following code to change the user account and password associated with a Windows Service. How can I modify this code to be able to perform the same operation on a remote system?
static void Main(string[] args)
{
string serviceName = "DummyService";
string username = ".\\Service_Test2";
string password = "Password1";
ServiceController sc = new ServiceController(serviceName);
Console.WriteLine(sc.Status.ToString());
if (sc.Status == ServiceControllerStatus.Running)
{
sc.Stop();
}
Thread.Sleep(2000);
sc.Refresh();
Console.WriteLine(sc.Status.ToString());
string objPath = string.Format("Win32_Service.Name='{0}'", serviceName);
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
object[] wmiParams = new object[11];
wmiParams[6] = username;
wmiParams[7] = password;
service.InvokeMethod("Change", wmiParams);
}
Thread.Sleep(2000);
Console.WriteLine(sc.Status.ToString());
if (sc.Status == ServiceControllerStatus.Stopped)
{
sc.Start();
}
Thread.Sleep(2000);
sc.Refresh();
Console.WriteLine(sc.Status.ToString());
}
Use ServiceController constructor overload that allows target machine-name to be specified
Modify WMI object path to include the target server.
new ManagementPath(
"\\\\ComputerName\\root" +
"\\cimv2:Win32_Service.Name='{0}'");
Make sure your user/password have sufficient rights on target machine, change those if not.

Categories

Resources