Pourquoi ne GetWindowThreadProcessId retourner la valeur 0 lorsqu'il est appelé à partir d'un service?
Lors de l'utilisation de la classe suivante dans une application console, et ayant au moins une instance de bloc-notes en cours d'exécution, GetWindowThreadProcessId
correctement renvoie une valeur non nulle id de thread. Toutefois, si le même code est inclus dans un Service Windows, GetWindowThreadProcessId
retourne toujours 0
et aucune exception n'est levée. Changer l'utilisateur le lancement d'un service en vertu d'être le même que celui de l'exécution de l'application de la console de ne pas altérer le résultat. Quelles sont les causes de GetWindowThreadProcessId
de retour 0
même si il est fourni avec une pièce d'hwnd? Et pourquoi est-elle fonctionner différemment dans l'application de console et le service? Note: je suis sous Windows 7 32-bit et de ciblage .NET 3.5.
public class TestClass
{
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
public void AttachToNotepad()
{
var processesToAttachTo = Process.GetProcessesByName("Notepad")
foreach (var process in processesToAttachTo)
{
var threadID = GetWindowThreadProcessId(process.MainWindowHandle,
IntPtr.Zero);
....
}
}
}
Console Code:
class Program
{
static void Main(string[] args)
{
var testClass = new TestClass();
testClass.AttachToNotepad();
}
}
Code De Service:
public class TestService : ServiceBase
{
private TestClass testClass = new TestClass();
static void Main()
{
ServiceBase.Run(new TestService());
}
protected override void OnStart(string[] args)
{
testClass.AttachToNotepad();
base.OnStart(args);
}
protected override void OnStop()
{
...
}
}
OriginalL'auteur dcharles | 2010-03-17
Vous devez vous connecter pour publier un commentaire.
Un service s'exécute dans sa propre session, l'infâme session 0 dans Vista et Win7. Cette session isole les services du bureau de l'utilisateur, il s'exécute dans une autre session. Spécifiquement pour empêcher un service qui s'exécute généralement avec un très privilégié de compte (comme LocalSystem) de l'interaction avec l'utilisateur. Un trou de sécurité.
En conséquence, un service ne peut pas voir les poignées de fenêtres appartenant à une autre session.
Pas sûr de savoir pourquoi vous le faites, mais vous n'avez généralement besoin d'un programme d'assistance qui offre une interface utilisateur et communique avec le service à travers un mécanisme IPC comme named pipes, sockets .NET remoting ou WCF. Si vous utilisez un tube nommé, préfixe le nom de canal avec
"Global\"
donc toutes les sessions peuvent le voir.OriginalL'auteur Hans Passant
Vous pouvez également activer l'option "Autoriser le service à interagir avec le bureau" et voir si cela fonctionne. Sinon je suis d'accord avec onbugz commentaire ci-dessus.
OriginalL'auteur Black Frog
Un Service Windows n'a pas d'INTERFACE utilisateur, de sorte qu'il n'a pas de fenêtre.
OriginalL'auteur John Saunders