用C#做了个windows服务程序,安装成功后,发现服务在初始化启动时,调用下面这个设置代理的系统api会没效果,也不报错,服务安装里的 account已经设为LocalSystem;感觉是权限问题,因为同样的程序做成winform的就正常,请各位大大帮忙看看,是何原因,该怎么处 理,谢谢
[DllImport("wininet.dll", EntryPoint="InternetSetOption", CharSet=CharSet.Ansi, SetLastError=true)]
private static extern bool InternetSetOptionList(IntPtr hInternet, int Option, ref INTERNET_PER_CONN_OPTION_LIST OptionList, int size);
internal bool SetToWinINET(string connectionName, ProxyOpearte proxyOperate)
你看下你启动的 winform 程序使用的帐号是啥,然后把你的服务的帐号也改成这个。
启动的 winform 程序的帐号 应该是登录当前系统的帐号,有哪里能设置吗?
服务里能使用的几个LocalService/NetworkService等貌似都不行,还请指教
@fenghuo: “控制面板”-〉“管理工具”-〉“服务”,在列表中找到你的服务,然后在服务上点击鼠标右键,选择“属性”,切换到“登录”选项卡,选择“此帐户”,输入你的登录帐户。
@Launcher: 多谢Launcher
有没方法能通过程序进行这个步骤?
@fenghuo: 你可以在服务安装程序中修改帐户。
@Launcher: 嗯 控制面板”-〉“管理工具”-〉“服务”,在列表中找到你的服务,然后在服务上点击鼠标右键,选择“属性”,切换到“登录”选项卡,选择“此帐户”,设置当前登录用户就正常了
修改账户是指这两项么,有没方法能获取自己的这两个信息?:
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
@fenghuo: 应该是。
@Launcher: 有没方法能通过服务程序自己能提升 运行服务的权限
或者获得这两个信息.?
@fenghuo: 你的想法可能行不通。因为服务的启动不是由你来控制的,所以你只能先把需要的权限设置好,OS 会控制启动。
一个进程自动提升为管理员权限的做法是通过 runas 参数重启自己,比如:
SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.lpVerb = L"runas";
sei.lpFile = szPath; // 应用程序路径。
sei.hwnd = hWnd;
sei.nShow = SW_NORMAL;
ShellExecuteEx(&sei) // runas Administrator ,启动新进程,当前进程需要关闭。
当然,UAC 的对话框还是会弹出来的,这是避免不了的。
换个角度来说,如果一个部署在OS的Windows服务可以轻易的就将自己提升为管理员权限,那么它就可以做很多事情了,这是不安全的。
@Launcher:多谢兄弟指点! 看来自动提升是不行了
@fenghuo: 请问最终解决方案?
@Albert Fei: 在安装时候,或者在安装后通过“服务”配置,将你的服务的启动帐户设置为你所需要的权限级别的帐户。
你碰到和你的一样的问题 不过我后来解决了
你是windows7系统?
是权限问题
xp和win7都试过,都有这个问题,怎么解决的呢.
@fenghuo:
你把你要运行的那个服务:选择 允许服务与桌面交互 这个选上。在windows xp下测试。
先看一下行不行。
@Albert Fei: 我在window7下调用了第三方的一个库解决的。
库名为:Cjwdev.WindowsApi.dll, Cjwdev.WindowsApi.xml;
示例代码
IntPtr userTokenHandle = IntPtr.Zero;
ApiDefinitions.WTSQueryUserToken(ApiDefinitions.WTSGetActiveConsoleSessionId()
, ref userTokenHandle);
ApiDefinitions.PROCESS_INFORMATION procInfo = new ApiDefinitions.PROCESS_INFORMATION();
ApiDefinitions.STARTUPINFO startInfo = new ApiDefinitions.STARTUPINFO();
ApiDefinitions.CreateProcessAsUser(userTokenHandle,
appPath,
arguments,
IntPtr.Zero,
IntPtr.Zero,
false,
0,
IntPtr.Zero,
null,
ref startInfo,
out procInfo);
if (userTokenHandle != IntPtr.Zero)
{
ApiDefinitions.CloseHandle(userTokenHandle);
}
xp 下没有测试。
@Albert Fei: 这个函数是什么功能,是不也是个系统api?
通过服务程序自己能提升 运行服务的权限吗
@fenghuo: 在c# 中可以调用。那二个文件一个是.dll,一个是xml文件。这二个加到bin下,引入引用。
使用时加入
using Cjwdev;
using Cjwdev.WindowsApi;
可以提升服务程序的运行权限。能让服务程序和其它可执行程序交互。
且调用了这个第三方的事dll后,可以不用选上允许服务与桌面交互选项。
我的方法你试好了没有,尤其是在windows xp下。我这里没有这个环境测试。你测试过麻烦通知我一下结果。
@Albert Fei: 多谢兄弟,不过不是很明白,这个函数该在哪里调用,appPath就是服务程序所在地址吗?
@fenghuo: 你在windows 服务中调用啊。
appPath参数 就是你要调用的程序所以路径(比如xxx.exe可执行程序地址);
你把你的 [DllImport("wininet.dll", EntryPoint="InternetSetOption", CharSet=CharSet.Ansi, SetLastError=true)]
private static extern bool InternetSetOptionList(IntPtr hInternet, int Option, ref INTERNET_PER_CONN_OPTION_LIST OptionList, int size);
internal bool SetToWinINET(string connectionName, ProxyOpearte proxyOperate)这段代码 写到控件台程序里生成可执文件。再用我的那个方法调用。把可执行文件路径传过去,和相关的参数传过去试试看。
@Albert Fei: 意思是appPath指向的是另外一个程序吗? 用服务去启动? 我是希望服务程序自己的运行权限哦
@fenghuo: 是个变通的方法。要不,不好调用这个。就是调用像你说的你在winform 下面能成功的程序就行了。
服务本身权限能不能提升我不清楚, 你用admin账号和密码运行的话,应该是最高的权限了。
只是操作系统现在对安全级别要求高了,一般不让服务去调用执行其它的程序而已。在低版本的操作系统上是可以与桌面程序交互的,也就是把那个复选框勾上就行了。
@Albert Fei: 如果外部程序 有参数呢 怎么传递?
@wangdm0824: 请问您解决了吗 参数怎么传递?
@kimty: 这个问题你搞定了吗?我现在也需要传递参数