我正在编写一个脚本,定期检查某些服务是否在远程工作站上运行.我有一段时间从一台测试机器到另一台测试机器上运行"SC\workst1查询"命令.两台机器都运行XP专业版SP3.两者都不是域名的一部分.两者都在同一工作组中,管理员帐户具有相同的密码.
我不断从任一工作站到另一个工作站获得"[SC] OpenSCManager FAILED 5:访问被拒绝"消息.我曾尝试在两者上使用提升权限.Windows防火墙软件已关闭.事件安全日志中没有消息显示.当(作为管理员)我尝试去"计算机管理" - >"连接到另一台计算机"并访问远程服务时,我得到"错误5访问被拒绝".
我可以成功地在两台机器之间建立文件系统共享,并且"net use\workst1\IPC $/user:Administrator"成功完成,但SC查询仍然失败.我在这些命令中使用的是IP地址而不是主机名,但这没有用.我不知道还有什么可以尝试的.谢谢您的帮助.
我想写一个侦听设备通知的服务(USB媒体插入,删除).在C#服务中侦听设备通知的问题System.Windows.Forms.Control.WndProc是因为Windows服务没有任何窗口而无法使用.
我发现了如何编写这样一个服务的HowTo.该文章的作者发现了一种解决方法,它允许服务侦听设备通知而不是服务控制消息,因此,该服务不再支持OnStop().
(更新26.01.13 :)
遗憾的是,我真的不了解服务控制管理器和Windows API.我想知道是否可以注册服务控制消息和USB设备通知,或者这是否真的是服务监听设备通知的唯一选择.我还没有找到任何(可以理解的)信息来解决我的问题.
可能使用System.Windows.Forms.Control.WndProc不生成窗口(我只需要添加System.Windows.Forms程序集,对吗?).
(更新27.01.13 :)
我刚发现这个问题:无法从Windows 7上
的Windows服务启动桌面应用程序第二个答案说,Windows服务在Windows Vista中接收了以安全为中心的改造,现在在Session 0中创建了GUI元素即使选中"允许服务与桌面交互"也是如此.这是否意味着,我可以创建一个Windows窗体然后接收USB设备事件(因此,我不需要弄乱ServiceControlHandler?是否有任何警告或问题这样做?
简而言之,我需要一个能够执行以下操作之一的解决方案:
我的源代码目前如下.它几乎与我在第一段中链接的HowTo提供的源代码相同.我做的唯一区别是删除FileSystemWatcher私有字段及其相同的所有用法因为我不需要FileSystemWatcher.
USBBackup.cs(服务本身 - 使用语句排除但在我的源代码中完整):
namespace USBBackup
{
public partial class USBBackup : ServiceBase
{
private IntPtr deviceNotifyHandle;
private IntPtr deviceEventHandle;
private IntPtr directoryHandle;
private Win32.ServiceControlHandlerEx myCallback;
private int ServiceControlHandler(int control, int eventType, IntPtr eventData, IntPtr context)
{
if (control == Win32.SERVICE_CONTROL_STOP || control == Win32.SERVICE_CONTROL_SHUTDOWN)
{
UnregisterHandles();
Win32.UnregisterDeviceNotification(deviceEventHandle);
base.Stop(); …Run Code Online (Sandbox Code Playgroud) 我正在处理记录到自定义事件日志的应用程序.应用程序最近已重新命名,事件日志的名称已更改(从"CompanyA Events"更改为"CompanyB Events").事件日志源("Subsystem1","Subsystem2"等)的名称未更改.应用程序安装程序从注册表中删除旧日志条目并写入新日志条目.
我注意到,在某些环境中(2008 R2上发生了很多),日志记录停止,并且没有写入任何事件.有时事件实际上写入OLD evtx文件,该文件本应被删除.以下修复了问题:
由于访问被拒绝,使用SCM无法实现后期操作,即使我是管理员.然而,杀死进程工作,我凸轮启动"Windows事件日志"服务,之后事件日志记录正常工作.
问题:如何在不杀死进程或重新启动计算机的情况下重新初始化事件日志服务?是否存在某种记录或未记录的调用,我可以使用它来指示事件日志服务应该重新读取其配置?
我使用以下命令创建了一个虚拟Windows服务:
sc create TestService binPath = C:\ Temp\TestService.exe DisplayName ="TestService"start = auto
它成功地在services.msc中创建了一个虚拟服务,但我还需要它来显示"已启动"状态.我知道这需要一些编码,我的TestService.exe是空白的.
知道怎么样?我通过网络搜索它需要MS Visual Studio 2010等.看起来太复杂,我只需要一个空白服务,显示将用于测试目的的"已启动"状态.
我有一个Windows服务,将文件导入数据库.当服务收到停止通知时,它应该尽可能完成当前导入.可能需要几分钟才能完成.
因此,我使用该ServiceBase.RequestAdditionalTime方法向SCM发出服务仍在工作且可操作的信号.
protected override void OnStop()
{
var waitTime = TimeSpan.FromSeconds(5);
var additionalWaitTime = TimeSpan.FromMinutes(3);
Trace.Write("Stopping service...");
var task = Task.Factory.StartNew(() => worker.Stop());
while (!task.Wait(waitTime))
{
Trace.Write("Requesting additional time...");
RequestAdditionalTime((int)additionalWaitTime.TotalMilliseconds);
Trace.Write("Waiting for {1} to complete...");
}
Trace.Write("Service stopped.");
}
Run Code Online (Sandbox Code Playgroud)
在测试时,我找不到使用该RequestAdditionalTime方法的服务的任何不同行为.如果我删除了RequestAdditionalTime呼叫,则服务的行为方式相同:
Stopping到我的工作人员完成为止.WaitToKillServiceTimeout)有什么影响RequestAdditionalTime?我应该在哪里看到使用它时的差异,我该如何测试呢?有几次我读到,如果没有请求额外的时间,SCM将终止服务.但我看不出那种行为.
所有在我的本地开发机器(Win 8.1)上运行的测试,假设其行为与Windows Server OS上的行为相同.
当通过服务控制管理器运行时,Windows服务需要假设可以在不同的线程上调用命令处理方法(OnStart,OnStop等),而不确保例如在方法之间可以看到成员的分配吗?
public class MyService : ServiceBase {
private Object _foo;
protected override void OnStart(string[] args) {
_foo = new Object();
}
protected override void OnStop() {
if (_foo == null) {
throw new Exception("Assignment not visible"); // Can this happen?
}
_foo = null;
}
}
Run Code Online (Sandbox Code Playgroud)
我无法保证我的示例中的异常不会被抛出,但我发现的所有示例(包括StackOverflow上的其他示例)似乎都假设,例如,OnStart()中变量的赋值将始终在OnStop()中可见.
如果SCM没有做出这样的保证,我就知道如何确保分配是可见的(例如,通过在服务中的所有读/写周围添加一个锁).我对这些措施是否必要感兴趣.
我试图使用以下代码控制远程计算机上的服务:
// Error checking omitted for brevity
HANDLE hToken = NULL;
// user = username with no domain specification
// domain = targetmachine when targetting computer outside of domain
LogonUser(user, domain, password,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &hToken);
ImpersonateLoggedOnUser(hToken);
SC_HANDLE hSc = OpenSCManager(targetmachine,
SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
Run Code Online (Sandbox Code Playgroud)
从使用当前登录用户的凭据以及使用其他凭据时,从本地域中的计算机运行并在同一域上定位计算机时,此方法可以正常工作.
但是,当我尝试定位不在任何域上的计算机时,OpenSCManager如果我指定除了SC_MANAGER_CONNECT所需访问之外的任何内容,则调用将失败并拒绝访问.从域外的计算机中定位域计算机(对于作为目标计算机上的本地管理员的域用户,使用用户/域/密码组合).从域外的计算机定位域外的计算机不起作用.
用户/密码是针对目标计算机上管理员组的成员,因此帐户权限不应存在问题.
我已经检查了scmanager安全描述符sc -sdshow scmanager,它对于域计算机和非域计算机是相同的.两者都运行Windows 7 64位.
我也测试过使用psexec,它有相同的症状,即在域计算机之间工作正常但在目标非域计算机时不能.
我还测试了在目标计算机上禁用RPC over TCP并重新启动它,因为这被描述为访问被拒绝错误的可能原因,但这似乎没有帮助.我还测试了在targetmachine上禁用Windows防火墙,但没有变化.
是否需要启用某些设置才能使远程服务配置正常工作?
windows ×4
c# ×3
service ×3
winapi ×2
cmd ×1
event-log ×1
exe ×1
mmc ×1
permissions ×1
windows-xp ×1