Running DLL/EXE program from windows service in Windows 7 - c#

I actually need an expert advice in resolving a situation regard calling InitPK.dll (C++ dll) as a service in windows 7 (Code attached). The dll is loaded successfully but PKAgentInit method is returning 0(false) on Windows 7 using windows service the same works okay in windows XP also the code works fine when exec as a console program on windows 7 .
Could you please guide us why PKAgentInit method is returning 0 on Windows 7 and what is the recommended way of calling Agent under Windows 7 using windows service.**
Code:
typedef UINT (CALLBACK* INITPK)();
m_LogDebug->Log(2,nThreadId,cMethod,
"Pre-requisite applications are running so executing Agent...");
hDll = LoadLibrary(AgentPath.c_str());
if(hDll == NULL)
{
m_LogDebug->Log(0,nThreadId,cMethod,
"Failed to load [%s]",AgentPath.c_str());
return false;
}
INITPK InitPK_Func;
if((InitPK_Func = (INITPK)GetProcAddress(HMODULE(hDll), "PKAgentInit")) == NULL)
{
m_LogDebug->Log(0,nThreadId,cMethod,
"Failed to load proc address [%s]",AgentPath.c_str());
return false;
}
UINT Res = InitPK_Func();
// returning 0 which means Agent is not executed successfully.
// Ideally it should return 1.
m_LogDebug->Log(0,nThreadId,cMethod,"PKAgentInit returned [%d]",Res);

Without seeing the source to InitPK_Func() it's hard to say but I'd guess that it's a privileges problem and the service isn't running as a user that can do what you need to do. Perhaps the code in question needs to be elevated (might be why it works on XP), or perhaps it's touching a network resource (might be why it works as a console app on Win7).
But really, you need to debug the problem function and maybe change it to return a little more information about why it failed.

Related

Autorun console application in linux

I have developed a console application using MVS and I compiled it so can run on linux.
It runs on linux when I manually run and everything works so far. But whenever I try to run it at boot using crontab it seems not to be working.
My application is a HttpListener. The linux environment I run this is a robot's. I've not used linux very much so I have found and used the below commands to get this run at boot.
#reboot /home/rauman/Downloads/webserver
Then I tried setting a delay of 20secs,
#reboot sleep 20 && /home/rauman/Downloads/webserver
I normally run this application with terminal like below and works fine
./webserver
I'm accessing the robot using putty
After adding this to run at boot, I could see the pid of the application,
pidof webserver
So I guess it runs, but got no permission or something?
I have given permission for the file using,
chmod +x webserver
Any help is appreciated.
Edit : Solved
As, Mr. R pointed out
#reboot sleep 20 && cd /home/rauman/Downloads/ && /.webserver
I ran into the same problem a few days ago. My app runs flawlessly when I call it from its working directory but it failed when getting called from outside. It turned out the app reads a file by a relative address. So I had to change either the program or the pwd.
The easiest way that I came by is changing pwd:
#reboot sleep 20 && cd /home/rauman/Downloads/ && ./webserver
crontab runs processes as root, so any another file (such configurations) beloning to your user profile folder cannot be accessibile by ¢rotab.
Is this you scenario?
If yes, you should them into /etc or into /root.

Process.Start() does nothing when called from a C# written service

I have created a service that works good, except for this section that don't do what I want
shutdownProcess.StartInfo.RedirectStandardError = true;
shutdownProcess.StartInfo.WorkingDirectory = #"C:\Program Files (x86)\Siemens\Automation\WinCC RT Advanced";
shutdownProcess.StartInfo.FileName = #"C:\Program Files (x86)\Siemens\Automation\HmiRtmShutdown.exe";
shutdownProcess.Start();
string errors = shutdownProcess.StandardError.ReadToEnd();
eventLog1.WriteEntry(errors, EventLogEntryType.Error, eventId++);
The problem is that the process is not executed;
as you can see I tried to record errors in a log, but the log records a empty string so it seems that there is no error;
This application works perfectly when I call it from cmd.exe; I also tried to use process.start() with cmd.exe passing the path as argument, but it did not work;
I installed the service as LocalSystem to give it maximum privileges;
I also tried to put the service into same folder and call only the .exe to exclude errors in writing the path; nothing
please help!
You cannot execute applications or executables which try to render a User Interface or are designed to require interactive login from a Windows Service which runs in background in UI less mode ( Session 0 from Vista onwards as others have comemnted ).
try to wite some unit tests and run your code from the unit tests in Visual Studio, if all works fine but then from the Windows Service does not work, then the problem is exactly the one explained above.

Application exit code always return 0

We have a legacy VB6 application that runs a separate C# EXE. The VB6 application relies on the C# application to perform a particular task. When the task is done successfully it will return with exit code 0, or 1 if failure.
This works well on our development machines (yes, we tried on more than 1 machine). But, when we tried it on the client machine it always returns a 0 exit code no matter the result of the task.
The really strange part is that this scenario has been working perfectly for about 8 months until this first happenned.
We even tried to make a simple C# 'runner app' that only calls an exe and catches its exit code. Again, it worked fine on our development machine but always return 0 on the client machine. So, we concluded that the problem is not in the VB6 program.
This is the C# 'runner app' code snippet that call the .exe program:
System.Diagnostics.Process installProcess = new System.Diagnostics.Process();
installProcess.StartInfo.FileName = this.textBox1.Text;
installProcess.StartInfo.Arguments = this.textBox2.Text;
installProcess.Start();
installProcess.WaitForExit();
MessageBox.Show("Exit code : " + installProcess.ExitCode.ToString());
And this is the C# code snippet that exit the program with custom exit code:
Environment.Exit(1);
Well, we suspect there's some configuration on the client machine OS that causes this strange behavior on the client machine.
Based on the comment from Michael Gosselin on this question, it is critical to compile your project as a "console application" and not as a "windows application".

Process.Start won't work

I am trying to launch a process from a web page's back-end code/app pool. This process will launch an App that i built myself.
For some reason, the process only works / runs when i start it from VS2013... it never works when i launch it from IIS(7.5) itself.
I am on a Windows 7 machine (both IIS host, and App location), and I've setup my web site to only be accessible via internal network.
Here's the code, followed by the config / attempts to fix the issue:
protected void btn_DoIt_Click(object sender, EventArgs e)
{
string file_text = this.txt_Urls.Text;
if (!String.IsNullOrWhiteSpace(file_text))
File.WriteAllText(ConfigurationManager.AppSettings["filePath"], file_text);
ProcessStartInfo inf = new ProcessStartInfo();
SecureString ss = GetSecureString("SomePassword");
inf.FileName = #"........\bin\Release\SomeExecutable.exe";
inf.Arguments = ConfigurationManager.AppSettings["filePath"];
inf.UserName = "SomeUserName";
inf.Password = ss;
inf.UseShellExecute = false;
//launch desktop app, but don't close it in case we want to see the results!
try
{
Process.Start(inf);
}
catch(Exception ex)
{
this.txt_Urls.Text = ex.Message;
}
this.txt_Urls.Enabled = false;
this.btn_DoIt.Enabled = false;
this.txt_Urls.Text = "Entries received and process started. Check local machine for status update, or use refresh below.";
}
Here are the things I've tried to resolve the issue:
Made sure the executing assembly was built with AnyCPU instead of
x86
Ensured that the AppPool that runs the app, also runs under the same account (SomeUsername) as the ProcessStartInfo specified.
Ensured that the specific user account has full access to the executable's folder.
Ensured that IIS_USR has full access to the executable's folder.
Restarted both the app pool and IIS itself many times over implementing these fixes
I am now at a loss as to why this simply will not launch the app... when i first looked into the event log, i saw that the app would die immediately with code 1000:KERNELBASE.dll, which got me on the AnyCPU config instead of X86 fix... that fixed the event log entries but the app still doesn't start (nothing comes up in task manager), and i get no errors in the event log...
if someone could help me fix this problem i would really appreciate it. This would allow me to perform specific tasks on my main computer from any device on my network (phone, tablet, laptop, etc etc) without having to be in front of my main PC...
UPDATE
The comment to my OP, and ultimate answer from #Bradley Uffner actually nailed the problem on the head: My "app" is actually a desktop application with a UI, and in order to run that application, IIS would need to be able to get access to the desktop and the UI, just like if it were a person sitting down in front of the PC. This of course is not the case since IIS is running only as a service account and it makes sense that it shouldn't be launching UI programs in the background. Also see his answer for one way of getting around this.
Your best bet might be to try writing this as 2 parts. A web site that posts commands to a text file (or database, or some other persistent storage), and a desktop application that periodically polls that file (database, etc) for changes and executes those commands. You could write out the entire command line, including exe path command arguments, and switches.
This is the only way I can really think of to allow a service application like IIS to execute applications that require a desktop context with a logged in user.
You should assign a technical user with enough high priviliges to the running application pool. By default the application pool is running with ApplicationPoolIdentity identy which has a very low priviliges.

what should i use instead of Directory.SetCurrentDirecory?

i have a multi environment program that runs on windows ce machines, regular pc and windows mobile.
I am using a database and files.
because of the windows CE i need to use the Directory.GetCurrentDirectory() func before the file use and then reset the current directory (using the Directory.SetCurrentDirectory() func) back to the old one because it changes once i do the I\O in order to continue using the DB.
because the windows mobile does not support this functions there is an exception thrown during runtime a "NotSupporetedException".
any functions that i could use instead of this that should fix my problem?
or any way i can check during runtime what environment the application is running on and not use this functions if the application runs on mobile?
please help,
thanks in advance.
I don't fully understand your directory problem, but you can certainly check which platform you're on at runtime:
if (Environment.OSVersion.Platform == PlatformID.WinCE)
{
...
}
else
{
...
}

Categories