mahmood66
asked on
problem in windows service in windows 7
Dear Experts,
i have a window service which would call an exe(my application) in a timely manner.
(Note : this service has been developed in VS2008 C#.My application is developed in
VS2003 C#).
In windows XP,this service is working perfectly.
In windows 7, whenever my service calls my exe ,windows 7 prompt a pop up( as i attached image). (but if i directly run the exe it is working in the same desktop without any issue.)
if i click 'view message', my exe ( application) is running in different environment unlike desktop along with one more small window(i couldn't able take even screen shot of that environment) .
I am using following code to call my exe(application)
kindly suggest me solution to run my application properly via my service.
Thanks
i have a window service which would call an exe(my application) in a timely manner.
(Note : this service has been developed in VS2008 C#.My application is developed in
VS2003 C#).
In windows XP,this service is working perfectly.
In windows 7, whenever my service calls my exe ,windows 7 prompt a pop up( as i attached image). (but if i directly run the exe it is working in the same desktop without any issue.)
if i click 'view message', my exe ( application) is running in different environment unlike desktop along with one more small window(i couldn't able take even screen shot of that environment) .
I am using following code to call my exe(application)
Process lobj_process = new Process();
lobj_process.StartInfo.FileName = "MyApp.exe";
lobj_process.StartInfo.WorkingDirectory = ls_path;
lobj_process.StartInfo.RedirectStandardInput = true;
lobj_process.StartInfo.UseShellExecute = false;
lobj_process.StartInfo.CreateNoWindow = false;
lobj_process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
lobj_process.Start();
ProcessWindowStyle ws = lobj_process.StartInfo.WindowStyle;
if (ws == ProcessWindowStyle.Hidden)
lobj_process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
lobj_process.WaitForExit();
lobj_process.Close();
kindly suggest me solution to run my application properly via my service.
Thanks
Windows Vista and later interactive services has been disabled by default. Instead of using the Process Class to open your executable use the following ServiceShell.Start() method will get the token of the current user and open the executable onto the users desktop instead of the services session. Your service can be set to LocalSystem
Imports System.Runtime.InteropServices
Imports System.Text
Public NotInheritable Class ServiceShell
Private Sub New()
End Sub
Private Const CreateUnicodeEnvironment As Integer = &H400
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Private Structure StartupInfo
Dim cb As Integer
<MarshalAs(UnmanagedType.LPTStr)> Dim lpReserved As String
<MarshalAs(UnmanagedType.LPTStr)> Dim lpDesktop As String
<MarshalAs(UnmanagedType.LPTStr)> Dim lpTitle As String
Dim dwX As Integer
Dim dwY As Integer
Dim dwXSize As Integer
Dim dwXCountChars As Integer
Dim dwYCountChars As Integer
Dim dwFillAttribute As Integer
Dim dwFlags As Integer
Dim wShowWindow As Short
Dim cbReserved2 As Short
Dim lpReserved2 As IntPtr
Dim hStdInput As IntPtr
Dim hStdOutput As IntPtr
Dim hStdError As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Private Structure ProcessInformation
Dim hProcess As IntPtr
Dim hThread As IntPtr
Dim dwProcessID As Integer
Dim dwThreadID As Integer
End Structure
<DllImport("Advapi32.dll", ExactSpelling:=False, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function CreateProcessAsUser(ByVal hToken As IntPtr, ByVal lpApplicationName As String, <[In](), Out(), [Optional]()> ByVal lpCommandLine As StringBuilder, ByVal lpProcessAttributes As IntPtr, ByVal lpThreadAttributes As IntPtr, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean, ByVal dwCreationFlags As Integer, ByVal lpEnvironment As IntPtr, ByVal lpCurrentDirectory As String, <[In]()> ByRef lpStartupInfo As StartupInfo, <Out()> ByRef lpProcessInformation As ProcessInformation) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("Userenv.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function CreateEnvironmentBlock(ByRef lpEnvironment As IntPtr, ByVal hToken As IntPtr, <MarshalAs(UnmanagedType.Bool)> ByVal bInherit As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("Userenv.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function DestroyEnvironmentBlock(ByVal lpEnvironment As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("Wtsapi32.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function WTSQueryUserToken(ByVal SessionId As Integer, ByRef phToken As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("Kernel32.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function WTSGetActiveConsoleSessionId() As Integer
End Function
<DllImport("Kernel32.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Public Shared Sub Start(ByVal filename As String, ByVal commandLine As String, ByVal workingDirectory As String, Optional ByVal sessionId As Integer = -1)
Dim hToken As IntPtr
Dim pEnvBlock As IntPtr
Dim dwSessionId As Integer
Dim pi As ProcessInformation = Nothing
Dim si As StartupInfo = Nothing
' If no session Id was specified defaults to using the session Id
' that is currently attached to the physical console.
If sessionId = (-1) Then
dwSessionId = WTSGetActiveConsoleSessionId()
Else
dwSessionId = sessionId
End If
' Obtain the primary access token of the logged-on user specified by the session
' * Note: This can only be called successfully under LocalSystem context.
If WTSQueryUserToken(dwSessionId, hToken) Then
' Get the enviorment block pointer for the user session.
If CreateEnvironmentBlock(pEnvBlock, hToken, False) Then
' Setup command line buffer for unicode version
Dim cmdLine As New StringBuilder(commandLine, 32768)
If CreateProcessAsUser(hToken, filename, cmdLine, IntPtr.Zero, IntPtr.Zero, False, _
CreateUnicodeEnvironment, pEnvBlock, workingDirectory, si, pi) Then
' cleanup handle information
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)
End If
' Destroy enviorment block pointer.
DestroyEnvironmentBlock(pEnvBlock)
End If
' cleanup user session token handle.
CloseHandle(hToken)
End If
End Sub
End Class
'// usage
ServiceShell.Start("c:\myapp.exe", " -commandlines", "c:\")
ServiceShell.Start("c:\myapp.exe", nothing, nothing)
ASKER
Dear egl1044,
i converted above code to C# as my code is in C#.
while calling Start() function
dwSessionId = WTSGetActiveConsoleSession Id()
the above function always returns '0'.so my application is not opening.
kindly suggest me what i need to do.
thanks
i converted above code to C# as my code is in C#.
while calling Start() function
dwSessionId = WTSGetActiveConsoleSession
the above function always returns '0'.so my application is not opening.
kindly suggest me what i need to do.
thanks
Is your service set to LocalSystem?
ASKER
Deat eg1044,
how can i set my service to localsystem?
how can i set my service to localsystem?
Check the properties section of your service and service installer files. The option should be in there
ASKER
Just a note. This was the place I referrred to in my post 36708597.
Yes. I'm referring to your actual service not the services.msc console but your service application within .NET. In Vista and later interactive services are disabled by default so you don't want to select "Interact with desktop option". You need to open your service in .NET and go to the properties section and turn off "interact with desktop" and only select LocalSystem.
Have a look here http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.80).aspx and scroll to the section "To create the installers for your service"
" In the designer, click ServiceProcessInstaller1 (for a Visual Basic project), or serviceProcessInstaller1 (for a Visual C# or Visual J# project). Set the Account property to LocalService. This will cause the service to be installed and to run on a local service account. "
Make sure you don't have interact with desktop enabled. You may have to un-install your service first, compile the changes and then re-install.
" In the designer, click ServiceProcessInstaller1 (for a Visual Basic project), or serviceProcessInstaller1 (for a Visual C# or Visual J# project). Set the Account property to LocalService. This will cause the service to be installed and to run on a local service account. "
Make sure you don't have interact with desktop enabled. You may have to un-install your service first, compile the changes and then re-install.
ASKER
Dear jagrut & eg1044,
1) i already set the above mentioned property.still my application opening in such environement in windows 7.
2) while debugging below code(which is suggested by you [ eg1044]),
Public Shared Sub Start(ByVal filename As String, ByVal commandLine As String, ByVal workingDirectory As String, Optional ByVal sessionId As Integer = -1)
Dim hToken As IntPtr
Dim pEnvBlock As IntPtr
Dim dwSessionId As Integer
Dim pi As ProcessInformation = Nothing
Dim si As StartupInfo = Nothing
' If no session Id was specified defaults to using the session Id
' that is currently attached to the physical console.
If sessionId = (-1) Then
dwSessionId = WTSGetActiveConsoleSession Id()
Else
dwSessionId = sessionId
End If
' Obtain the primary access token of the logged-on user specified by the session
' * Note: This can only be called successfully under LocalSystem context.
If WTSQueryUserToken(dwSessio nId, hToken) Then
' Get the enviorment block pointer for the user session.
If CreateEnvironmentBlock(pEn vBlock, hToken, False) Then
' Setup command line buffer for unicode version
Dim cmdLine As New StringBuilder(commandLine, 32768)
If CreateProcessAsUser(hToken , filename, cmdLine, IntPtr.Zero, IntPtr.Zero, False, _
CreateUnicodeEnvironment, pEnvBlock, workingDirectory, si, pi) Then
' cleanup handle information
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)
End If
' Destroy enviorment block pointer.
DestroyEnvironmentBlock(pE nvBlock)
End If
' cleanup user session token handle.
CloseHandle(hToken)
End If
End Sub
this function("WTSGetActiveCons oleSession Id()") always returns '0 ' as sessionId.
so my application is not opening(if i use that code)...
3) is there any other way to avoid opening of my application in such environment in windows 7?
should i approach some other method specially for windows 7.?
because my service opens the same application in XP without any problem, as i mentioned in my question
kindly suggest me..
thanks
1) i already set the above mentioned property.still my application opening in such environement in windows 7.
2) while debugging below code(which is suggested by you [ eg1044]),
Public Shared Sub Start(ByVal filename As String, ByVal commandLine As String, ByVal workingDirectory As String, Optional ByVal sessionId As Integer = -1)
Dim hToken As IntPtr
Dim pEnvBlock As IntPtr
Dim dwSessionId As Integer
Dim pi As ProcessInformation = Nothing
Dim si As StartupInfo = Nothing
' If no session Id was specified defaults to using the session Id
' that is currently attached to the physical console.
If sessionId = (-1) Then
dwSessionId = WTSGetActiveConsoleSession
Else
dwSessionId = sessionId
End If
' Obtain the primary access token of the logged-on user specified by the session
' * Note: This can only be called successfully under LocalSystem context.
If WTSQueryUserToken(dwSessio
' Get the enviorment block pointer for the user session.
If CreateEnvironmentBlock(pEn
' Setup command line buffer for unicode version
Dim cmdLine As New StringBuilder(commandLine,
If CreateProcessAsUser(hToken
CreateUnicodeEnvironment, pEnvBlock, workingDirectory, si, pi) Then
' cleanup handle information
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)
End If
' Destroy enviorment block pointer.
DestroyEnvironmentBlock(pE
End If
' cleanup user session token handle.
CloseHandle(hToken)
End If
End Sub
this function("WTSGetActiveCons
so my application is not opening(if i use that code)...
3) is there any other way to avoid opening of my application in such environment in windows 7?
should i approach some other method specially for windows 7.?
because my service opens the same application in XP without any problem, as i mentioned in my question
kindly suggest me..
thanks
This is the correct way to launch an application from a service onto the desktop. The example provided works as intended but there must be some minor problem on your side. In XP the option "interact with desktop" is what allows the service to display the application on the desktop however on Vista and later this has been removed. The easiest way to make it work for XP, Vista , Win7 is to NOT enable "interactive with desktop" option and use the example code to launch your application. The example code will open your program on the current desktop.
ASKER
Dear (egl1044) Experts,
i have created a new service as suggested in previous post(ID: 36716188).
i followed the instruction and i did the code.
i used the suggested code to call an exe.(suggested By egl1044 ID :36708830)
(but i have converted the code into c#.)
still this is not working..
kindly send me one sample project to achieve my target..
thanks
i have created a new service as suggested in previous post(ID: 36716188).
i followed the instruction and i did the code.
i used the suggested code to call an exe.(suggested By egl1044 ID :36708830)
(but i have converted the code into c#.)
still this is not working..
kindly send me one sample project to achieve my target..
thanks
mahmood66, just to re-emphasis my point I would like to repeat that services are not meant to open a windows form. Just consider the case where computer is started but user does not log-in. Service is started in such case but how can it show the UI.
It is my suggestion that if possible you should think of other alternative like having a System tray application that can start automatically when application starts.
It is my suggestion that if possible you should think of other alternative like having a System tray application that can start automatically when application starts.
ASKER
can you give me coding example for that.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Dear Jagrut,
Thanks for your suggestion.it works.
Thanks for your suggestion.it works.
ASKER
it works
Still to do so you can try this option and check.
In Property of your service > LogOn tab > Select Local System Account > Check "Allow service to interact with desktop" option.