20070527 SaferRun 1.00
http://www.yippeesoft.com
SaferRun:DropMyRights GUI程序
原理+源代码:
http://www.microsoft.com/china/msdn/library/security/ussecure11152004.mspx?mfr=true
CreateProcessAsUser() windowstations 和桌面
http://support.microsoft.com/kb/165194/
CreateProcessAsUser在c#中的调用
http://www.cnblogs.com/liefeng123/archive/2006/10/19/533743.html
The Windows Access Control Model Part 2
http://www.codeproject.com/win32/accessctrl2.asp
SaferRun.xml
<?xml version="1.0" encoding="utf-8"?>
<saferrun>
<menunum>1</menunum>
<menu0 name="IE">D:\\Program Files\\Internet Explorer\\iexplore.exe</menu0>
</saferrun>
从这里LOAD菜单,显示为NAME 字样
点击后 以普通用户运行指定程序
显示在状态区
需要.NET FRAMEWORK 2.0
本来想都用C#,不过那些函数IMPORT太麻烦,干脆用VC封装DLL,C# 再传递STRING
本来想增加XML编辑,如增加 删除 编辑等,不过那种处理太烦琐了,算了
editplus、ms word等编辑器都可以使用alt选择的方法 切换到 列模式
xd.Load("E:/test.xml");
给定编码中有无效的字符。
XML以<?xml version="1.0" encoding="utf-8"?> 编码格式保存
标签:err, saferrun 20070526 SaferRun 开发 ToolStripMenuItem
http://www.yippeesoft.com
C#代码辅助工具Visual Assist X 与 VS2005的代码自动提示发生冲突的解决办法
在 Visual Assist X 设置好代码快捷方式以后,比如 if 的快捷方式设置成:
if($select$)
&leftsign;
$end$
&rightsign;
在VS代码编辑窗口中编辑时,发现与VS自己的 if 快捷方式发生了冲突,Assist 的if出不来。
于是设置VS的属性N次,找到了解决问题的办法,如下:
工具 >> 选项 >> 文本编辑器 >> C#
1、常规: 将“语句结束”自动列出成员,隐藏高级成员选中
2、Intellisense:将“完成列表”中的“键入字符后显示完成列表”去掉,不选中。其他的项目不去动他。
C# winform程序中动态菜单的问题
给应用程序动态增加菜单
例:
popMenuItem 是父菜单,可以是菜单条上的主菜单项目也可以是下拉菜单中的菜单项
DynMenuItem_Click(object sender, EventArgs e) 是菜单响应函数
&leftsign;
ToolStripMenuItem item = (ToolStripMenuItem)sender;
item 是当前单击的新菜单项
&rightsign;
ToolStripMenuItem item = new ToolStripMenuItem("动态菜单Text" ,null,new System.EventHandler(this.DynMenuItem_Click),"menuItemName");
popMenuItem.DropDownItems.Add(item);
c# 分隔符 new ToolStripMenuItem
private void Form1_Load(object sender, EventArgs e)
&leftsign;
XmlDocument doc = new XmlDocument();
//如果网络不畅的话则有可能会抛出WebException的。
doc.Load(tvListPath);
XmlElement ele = doc.DocumentElement;
XmlNodeList nodeList = ele.SelectNodes("item"); //得到一个名字为IIFF的所有节点
ConfigMainMenu(nodeList, this.menuStrip1, null);
&rightsign;
//包含菜单项内容的xml文件的地址。
private const string tvListPath = @"http://uploadlist.googlepages.com/OnlineTV.xml";
private void commonToolStripMenuItem_Click(object sender, EventArgs e)
&leftsign;
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
Debug.Assert(menuItem != null);
//未set的Name取出来的将是"",所以如此进行判断
if (menuItem.Name != "")
&leftsign;
Process.Start(menuItem.Name);
&rightsign;
&rightsign;
/**//// <summary>
/// 递归函数,向主窗体中加入菜单项。
/// </summary>
/// <param name="nodeList"></param>
/// <param name="menuStrip"></param>
/// <param name="menuItem"></param>
public void ConfigMainMenu(XmlNodeList nodeList, MenuStrip menuStrip, ToolStripMenuItem menuItem)
&leftsign;
foreach (XmlNode node in nodeList)
&leftsign;
if (node.Name == "item")
&leftsign;
XmlAttributeCollection attribute = node.Attributes;
XmlAttribute text = attribute["text"];
if (text != null)
&leftsign;
XmlAttribute address = attribute["address"];
//根据xml文件的内容新建一个菜单项。
ToolStripMenuItem subItem = new ToolStripMenuItem(text.Value);
if (address != null)
&leftsign;
subItem.Name = address.Value;
&rightsign;
subItem.Click += new EventHandler(commonToolStripMenuItem_Click);
addItem(menuStrip, menuItem, subItem);
ConfigMainMenu(node.ChildNodes, null, subItem);
&rightsign;
&rightsign;//如果指示为分隔符的话:
else if (node.Name == "separator")
&leftsign;
ToolStripSeparator toolStripSeparator = new ToolStripSeparator();
addItem(menuStrip, menuItem, toolStripSeparator);
&rightsign;
else
&leftsign;
throw new InvalidDataException("节点的名称有误,请检查");
&rightsign;
&rightsign;
&rightsign;
20070525 SaferRun 开发 用户权利 c# menu
http://www.yippeesoft.com
用户权利简介管理员可以指派特定权利组帐户或单个用户帐户。这些权利批准用户执行特定的操作,如交互式登录系统或备份文件和目录。用户权利与权限不同,因为用户权利适用于用户帐户,而权限则附加给对象。有关权限的信息,请参阅继承如何影响文件和文件夹的权限。
用户权利定义了本地级别上的功能。虽然用户权利可以应用于单个的用户帐户,但最好是在组帐户基础上管理。这样可以确保作为组成员登录的帐户将自动继承该组的相关权利。通过对组而不是对单个用户指派用户权利,可以简化用户帐户管理的任务。当组中的用户都需要相同的用户权利时,您可以一次对该组指派用户权利,而不是重复地对每个单独的用户帐户指派相同的用户权利。
对组指派的用户权利应用到该组的所有成员(在它们还是成员的时候)。如果用户是多个组的成员,则用户权利是累积的,这意味着用户有多组权利。指派给某个组的权利只有在特定登录权利的情况下才会与指派给其他组的权利发生冲突。然而,指派给某个组的用户权利通常不会与指派给其他组的权利冲突。要删除用户的权利,管理员只需简单地从组中删除用户。在这种情况下,用户不再拥有指派给这个组的权利。
有两种类型的用户权利:特权,如备份文件和目录的权利;另一种是登录权利,如登录到本地系统的权利。
详细信息,请参阅特权和登录权利。
c#中,在load事件中Form不能用Hide()方法?
试试看,好像没有效。
问题解决了,是在Form1_Activated中加入this.Hide();。
D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\Csc.exe /noconfig /nowarn:1701,1702 /warn:4 /define:DEBUG;TRACE /reference:D:\\WINDXP\\assembly\\GAC_MSIL\\Microsoft.VisualStudio.QualityTools.UnitTestFramework\\8.0.0.0__b03f5f7f11d50a3a\\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll /reference:"H:\\temp\\My Documents\\Visual Studio 2005\\Projects\\SaferRun\\SaferRun\\bin\\Debug\\SaferRun.exe" /reference:D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\System.Data.dll /reference:D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\System.Deployment.dll /reference:D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\System.dll /reference:D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\System.Drawing.dll /reference:D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\System.Windows.Forms.dll /reference:D:\\WINDXP\\Microsoft.NET\\Framework\\v2.0.50727\\System.Xml.dll /debug+ /debug:full /optimize- /out:obj\\Debug\\TestProject1.dll /target:library ProgramTest.cs Properties\\AssemblyInfo.cs Resources.DesignerTest.cs SaferRunTest.cs Settings.DesignerTest.cs VSCodeGenAccessors.cs
H:\\temp\\My Documents\\Visual Studio 2005\\Projects\\SaferRun\\TestProject1\\SaferRunTest.cs(78,44): 错误 CS0118: “SaferRun”是“命名空间”,但此处被当做“类型”来使用
SaferRun.SaferRun target = new SaferRun();
using SaferRun;
今天上午用VS的WebApplication编一个站外提交的程序的时候在调试的过程中出现 “HttpWebRequest”是“命名空间”,但此处被当做“类型”来使用”的报错信息,一开始以为是我的程序有问题(还怀疑是不是 WebApplication的问题),而后用Asp.net来实现没有任何问题,吃过饭后来重新建立了一个WebApplication程序居然没有任何报错,此时心里非常高兴,因为可以排除WebApplication的因素了,最终分析原因居然是我用了HttpWebRequest这个名称作为项目的名称的问题,将项目名称更换成Http_Request调试通过。
由此可以看到微软VS工具还是有些不完善的地方的,报错信息不是很人性化,当然希望大家也不要向我一样犯此等低级错误,在项目命名的时候尽量不要将名称特殊化和简单化,并且避免使用中文目录名或者项目名称,切记!
命名空间和类同名
有多个根元素
有多个根元素。 行 109,位置 9。
make sure your string is a valid xml string, which means, one root element,…
String YourString = "<Data><hangbiaoshi>1</hangbiaoshi><name>ee</name></Data>";
StringReader reader = new StringReader(YourString);
DataSet ds = new DataSet();
ds.ReadXml(reader);
foreach (DataTable t in ds.Tables)
&leftsign;
Console.WriteLine("&leftsign;0&rightsign; has &leftsign;1&rightsign; records", t.TableName, t.Rows.Count);
foreach (DataColumn dc in t.Columns)
Console.WriteLine(dc.ColumnName);
&rightsign;
or if you see that error, add "<DataSet>" + YourString + "</DataSet>"
Dim Menu As New ContextMenuStrip
Menu.Items.Add("添加")
不知如何将MenuAdd_Click()的过程加给生成的快捷菜单的"添加"的Click事件
也就是说:生成的快捷菜单的"添加"的Click后,运行我已经写好的MenuAdd_Click()过程
Dim Menu As New ContextMenuStrip
Dim MI As MenuItem = Menu.Items.Add("添加")
AddHandler MI.Click, AddressOf MenuAdd_Click
this.contextMenuStrip1.Items.Add(toolStripMenuItem1);
Step1.我们需要建立项目文件与测试文件的映射关系.
难道要我们去手动创建吗?这可是整个项目啊,里面也许包含了几十个类,数百个方法…当然没那么复杂!实际上,我们需要做的工作很少,只是动动鼠标,等几秒就可以了:)
在VS2005 的IDE环境下,选择menu里的Test,继续选New Test项,这时将跳出个窗体,里面可以选择测试项目类型,这里我们选择Unit Test Wizard,确定,输入测试项目名,然后将又出现一个窗体,里面包含你当前的solution里的所有project,我们选上我们的MyCache, 确定.OK,看见一个进度条,这是在执行测试代码的映射工作,等结束后,你就会发现,已经建立了一个测试项目了,里面的文件完全对应你的目标项目,每个类包含的方法也是与目标类的方法一一对应,非常简单,cool,mission complete!
Step2.运行我们的测试项目.
接下来,我们怎么进行测试呢?里面有许多的类和方法,很多方法上还带有像TestMethod这样的标签属性,但是我们关心的是,如何进行测试?绝对不是通常的F5来运行:(,在VSTS里,单元测试实际上有专门的管理工具.再次选到menu上的Test选项,移到windows上展开自菜单,里面有好几个选项,我们选择TestManager打开.在IDE窗口内出现了一个视图结构的东西,在分割线的右边是一个listView,里面全是当前测试项目包含的方法,我们随便选几个方法给勾上,右键,Run Checked Test,下边马上有出现了Test Result窗体,里面就是刚才你选择的方法.如果不出意外的话,你的这个窗体内的方法result应该都是failed之类的数据,嗯,先不管这个,最起码,我们已经运行了一次测试项目了,虽然有些奇怪,不过我们已经知道了如何运行一个测试项目了,那么再进入下一个step吧:)
Step3.看看我们的测试代码里都有些什么.
虽然知道了怎么运行测试项目,但莫名其妙的全部出错,是怎么回事呢?我们进入测试项目具体的代码来看看.
我们会发现,每个测试类的名称就是对应的目标类的名称+"test",里面的方法也是如此,如果是构造函数,则是诸如
ConstructorTest 或ConstructorTestN这样的形式,N为重载次数.每个方法里面的代码看上去也不奇怪,只是构造参数来调用而已,最后通过断言来判断(用过 NUnit的朋友不会陌生吧?).我们试着直接把一个方法里的断言去掉看看,编译,TestManager,run,嘿,果然,去掉断言的方法就pass 了!看来蒙老大不难呢,只要把所有的方法的断言都给去掉,然后给老大看测试后的结果,呵呵…
Step4.深入的了解一下方法上带有的属性的含义.
每个方法上几乎都带有TestMethod这个属性,我们直觉告诉我们,这肯定是表示被测试函数的意思.事实也正是如此,在Unit Test里,有许多测试属性,常用的如下:
属性 描述
TestClass()
该属性表示一个测试装置。
TestMethod()
该属性表示一个测试用例。
AssemblyInitialize()
在执行为执行选择的第一个 TestClass() 中的第一个 TestMethod() 之前,执行带有该属性的方法。
ClassInitialize()
带有该属性的方法在执行第一个测试之前调用。
TestInitialize()
带有该属性的方法在执行每个 TestMethod() 之前调用。
TestCleanup()
带有该属性的方法在执行每个 TestMethod() 之后调用。
ClassCleanup()
带有该属性的方法在执行 ALL 测试之后调用。
AssemblyCleanup()
在执行为执行选择的第一个 TestClass() 中的第一个 TestMethod() 之后,执行带有该属性的方法。
Description()
提供关于给定 TestMethod() 的描述。
Ignore()
由于某种原因忽略 TestMethod() 或 TestClass()。
ExpectedException()
当测试特定异常时,如果使用该属性指定的异常不是从实现代码引发,则测试不会失败。
需要注意的是,上面的属性不是可以适用于所有方法的,比如AssemblyInitialize()和ClassInitialize()是必须是静态方法的属性.
我们可以把初始化的操作放在他们里进行.
Step5.修改测试方法及其断言.
到现在,我们的思路开始清晰起来了,我们要开始做真正的测试了,不是仅仅去掉断言就pass那么简单了:)
我们的测试思路应该是这样:我们调用该方法,需要传入什么值,会影响什么值,当它执行之后,会产生怎样的期待值?我们把期待值与实际的值想比较,同时写下断言失败的message.
还是以我们的MyCahce为例,假如我们有个ListCache类,里面有个AddItemToTop(item)方法,表示把一个item插入到当前链表的头部.我们实际的测试函数该这么写
Guid id = System.Guid.NewGuid();
Item item = new Item(id);
list.AddItemToTop(item);
Assert.AreEqual(id, roomList.FirstLinkedItem.Key, "插入后查询获得的key值与插入的对象的key值不相等!");
通过比对插入后的链表的头部的key与之前保存的key值来判断,这是不是一次成功的插入.
这只是个很简单的例子,我们当然应该根据具体的方法需要实现的功能来定义测试代码.
Step6.OVER
完成了上面5部,相信你已经对VSTS的Unit Test非常的熟悉了,接下来需要做的就是把你需要的测试的method都提供正确的测试代码,注意,这里我们甚至不要考虑我们本身的项目究竟有没有实现该功能,但我们应该该知道,我们需要什么功能.我们只针对应该产生的结果写测试代码.当测试不通过时,我们只需要修改我们的目标项目,而不再需要修改我们的测试项目.这其实正是TDD(测试驱动开发)的思想,我们如果要验证我们的方法有没有错,只需要run一下test即可,真正实现了全自动化单元测试, 这里边的实际开发效率的提高,只有你在真正体会过后才能明白:)
20070524 SaferRun 开发
http://www.yippeesoft.com
error C2065: “_lpa” : 未声明的标识符
error C2065: “_convert” : 未声明的标识符
error C2065: “_acp” : 未声明的标识符
error C3861: “_lpa”: 即使使用参数相关的查找,也未找到标识符
error C3861: “_convert”: 即使使用参数相关的查找,也未找到标识符
error C3861: “_lpa”: 即使使用参数相关的查找,也未找到标识符
error C3861: “_convert”: 即使使用参数相关的查找,也未找到标识符
#include <atlconv.h>
USES_CONVERSION;
LPSTR lpstr = OLE2A(bstrVal); // bstrVal为BSTR类型变量
USES_CONVERSION是个宏,展开后定义一些局部变量以供WideCharToMultiByte或 MultiByteToWideChar使用,因为上面各位说的各种转换方法归根结底都是通过这两个函数进行转换的,只不过包装方法不同而已。下面的代码摘自MFC源码
#define USES_CONVERSION int _convert; _convert; UINT _acp = GetACP(); _acp; LPCWSTR _lpw; _lpw; LPCSTR _lpa; _lpa
#define A2W(lpa) ( ((LPCSTR)lpa == NULL) ? NULL : ( _convert = (strlen(lpa)+1), AfxA2WHelper((LPWSTR) alloca(_convert*2),
lpa, _convert) ))
但是还有个函数(StringCchLength())不能识别,又到MSDN里一查,少加这个函数所在的头文件(strsafe.h)
DLL的export
DLL中包含有一个表,称为export table(以下简称ET),其中包含了DLL中可以被外部程式使用的所有函数和数据的名字。只有记录在ET中的函数和数据才可以被外部程式所使用(如果没有.DEF文件的话),其它所有没有记录在ET中的函数和数据都被视为是DLL私有的。因此,要将DLL中的函数和数据export只有两个方法:
l 为DLL创建一个.DEF文件(模块定义文件),并在build该DLL时使用这个.DEF文件。使用这种方法使你可以将函数按序号export。
l 在DLL中想要export的函数和数据定义前添加_declspec(dllexport)关键字(对于函数和变量定义,加在最前面;对于class定义,加在class关键字后),这样该函数和数据就会被添加到ET中。使用这种方法函数将按名字export。
在WINDOWS下,无论使用上述的哪一种方法,都必须要将export函数声明为_stdcall。
c#调用dll问题,在vb里可以调通,可在c#中不知道什么问题
自己写的mydll.dll,用vc做的
包括有函数类似,myfunc(LPSTR string1)
用vb调声明之后,直接myfunc("323435")没有问题
可在c#中,声明之后,同样myfunc("323435")
发现传过去的参数,只取了第一个字符,此时的string1="3"
是不是这跟字符编码有关?
[DllImport(“MyDLL.dll”)]在申明的时候还可以添加几个属性
[DllImport(“MyDLL.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)
]
EntryPoint: 指定要调用的 DLL 入口点。默认入口点名称是托管方法的名称 。
CharSet: 控制名称重整和封送 String 参数的方式 (默认是UNICODE)
CallingConvention指示入口点的函数调用约定(默认WINAPI)(上次报告讲过的)
SetLastError 指示被调用方在从属性化方法返回之前是否调用 SetLastError Win32 API 函数 (C#中默认false )
如果是用的大小顺序的字节码
System.Text.Encoding.BigEndianUnicode.GetString(byte[]);
如果是用的小大顺序的unicode
System.Text.Encoding.Default.GetString(byte[]);
oCharArray()函数实现的是从字符串到Unicode 字符数组的转换的,
它有两种形式,你用的是第二种,第一个参数代表数组的起始位置,第二个参数代表转换长度,
这种方式适合已经定义好的数组(而不是声明好的数组),
如果是想把一个字符串完全转换到另一个数组中,那么就用它的第一种形式,不带参数的。
string yb = "abc";
char[] yy = yb.ToCharArray()
正解:CharSet = CharSet.Ansi
C#调用vc写的dll,出现找不到入口点
do this:
extern "C" __declspec(dllexport) BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
&leftsign;
return TRUE;
&rightsign;
you need to export the function.
写了一个vc++的dll, 利用 [DllImport] 调用,运行没有错误, 无法到达dll中的源代码中设置的端点,端点处为问号,提示为“无法命中端点,该文本没有加载任何符号”,结果是没法去调试该dll, 我试过了, 第一, 我都试过了,无论从c#那个工程作为启动工程或者是vc那个dll作为启动工程,都到达不了预先设置的断点,从模块加载窗口中,看不到该dll被加载,我在怀疑DllImport的机制。
第二,那个dll若不是基于.net平台, 根本就不让加。所以附加的方式也是不对的!
正解:把C#项目属性改为启用非托管调试。将dll依附的进程的DEBUG TYPE设置为MIXED TYPE即可,即托管[managed]和本地[native]混合模式即可
标签:err, saferrun, 开发20070523 SaferRun 资料
http://www.yippeesoft.com/
以管理员身份安全地浏览 Web 和读取电子邮件
http://www.microsoft.com/china/msdn/library/security/ussecure11152004.mspx?mfr=true
“用管理帐户运行会危及您的计算机和数据”,对此我已经说过多次,但是我将再重申一遍。因此,当某个人说他们必须以管理员身份操作计算机时,我总是试图说服他们,从安全的角度来看,这不是正确的操作。说归说,我偶尔也会碰到理由充分的人。例如,我使用办公室内的某台计算机安装最新的 Windows 日更新版本,并且我需要以管理员身份安装 OS。但是,当我以管理员身份在该计算机上运行时,不会以任何方式读取电子邮件、浏览 Web 或访问 Internet,这一点很重要。我之所以不这样做,是因为 Web 是当今大多数令人讨厌的攻击的来源。
如果某个人确实希望浏览 Web,该怎么办?亦或是读取电子邮件,或者进行即时消息处理等,而且由于某种原因必须在管理上下文中运行,那该怎么办?如果您查看对计算机的主要威胁,就会发现它们都来自用户通过浏览器和电子邮件客户程序等工具与 Web 进行的交互。
Windows XP 和 Windows Server 2003 以及更高版本都支持名为软件限制策略(又称为 SAFER)的功能,该功能允许用户或软件开发人员以较低的特权运行代码,而无需让用户在应用程序启动时输入凭据信息。例如,管理员可以在应用程序启动时,从应用程序的令牌中去掉某些 SID 和特权,从而以普通用户身份运行应用程序。一些应用程序(最典型的是面向 Internet 的应用程序,如 Web 浏览器、即时消息或电子邮件客户程序)绝对不能在管理上下文中运行。
返回页首返回页首
DropMyRights 应用程序
DropMyRights 是一个非常简单的应用程序,它可以帮助那些必须以管理员身份运行的用户在更安全的上下文(非管理员的上下文)中运行应用程序。这是通过以下方法来完成的:提取当前用户的令牌,从该令牌中删除各种特权和 SID,然后使用该令牌启动另一个进程(如 Internet Explorer 或 Outlook)。该工具完全适用于 Mozilla 的 Firefox、Eudora 或 Lotus Notes 电子邮件。
http://www.codeproject.com/csharp/accessctrl3.asp
This four part series will discuss the Windows Access Control model and its implementation in Windows NT and 2000. In the third part of the series, we will delve into the new security classes introduced for version 2.0 of the .NET framework.
I\’m not sure if you have read parts 1 and 2 of this series. If you are new to ACL based security and haven\’t read part 1[^], I strongly recommend you read it before continuing. (Don\’t worry. Even though it\’s in the C++ section, there isn\’t much C++ code in it.) Part 2 should be safe to skip if you are a .NET programmer. To prepare for part 3, make sure you have a copy of Visual Studio 2005 and the .NET Framework v2.0 (currently in beta 2).
This article is based on a pre-release version of Visual Studio. The framework may change in future releases, meaning the code may not work in the final version.
http://support.microsoft.com/kb/165194/
CreateProcessAsUser() windowstations 和桌面
通过的 CreateProcessAsUser 函数, 启动进程时进程将会启动到 windowstation 和桌面组合根据 lpDesktop STARTUPINFO 结构参数中的值:
• 如果 windowstation 和桌面组合 lpDesktop 成员, 中指定系统将尝试启动到该 windowstation 和桌面进程。
• 如果 lpDesktop 成员初始化为 NULL, 系统将尝试使用同一 windowstation 和桌面作为调用进程如果系统是与交互 windowstation。
• 如果不 lpDesktop 成员初始化为 NULL, 系统将创建新 windowstation 和桌面, 您无法看到。
• 如果用空字符串, 初始化系统 " "、 将或者创建新 windowstation 和桌面, 无法看到, 或通过相同如果之一是否已创建通过的以前调用访问令牌, 现有 windowstation, 将使用桌面。
http://www.cnblogs.com/liefeng123/archive/2006/10/19/533743.html
在windows系统中,有时需要在程序中以其他用户身份运行另外的exe程序,需要用
到advapi32.dll中的CreateProcessAsUser函数,在msdn中该函数原型为:
BOOL CreateProcessAsUser(
HANDLE hToken,
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation);关于个参数的具体说明msdn上有详细说明
就不在这里重复了。
需要提出说明的是hToken参数,在使用这个函数的时候,token 需要采用DuplicateTokenEx
函数来复制当前的token否则会出现1349的错误。关于DuplicateTokenEx的具体说明请参阅msdn.
http://www.codeproject.com/win32/accessctrl2.asp
This 4 part series will discuss the Windows Access Control model and its implementation in Windows NT and 2000.
In this second article we will start programming with security identifiers, access control lists and security descriptors. We will solve trivial problems using the SID, obtain information from an access token, enable a privilege, fill up an access control list, and finally we will check if we have access to a resource. The demo project provided is a Whoami clone written in Windows 2000 style. The source code includes equivalent programs of the article\’s code written with the low level APIs, the Windows 2000 APIs, and the Active Template Library.
http://www.codeproject.com/win32/accessctrl2.asp
http://www.tutorials-se.com/platformsdksecurity/Vista-admin/
Vista: How can an admin application start another application in the standard user context?