片段代码笔记
1 | /// <summary> |
片段代码笔记
1 | /// <summary> |
参考:
SqlBulkCopy 类
http://raylei.cn/index.php/archives/74/
https://www.cxybb.com/article/weixin_30333885/96361368
来自数据源的 Decimal 类型的给定值不能转换为指定目标列的类型 datetime
实际情况可能很复杂,使用的是泛型进行实体类转DataTable,可能会出现各种类型错误提示。
自己使用的是调用Copy()方法。
demo:
1 | var TableStruct = dal.GetTableStruct(); |
1 | /// <summary> |
1 |
|
现有一文件,其扩展名未知或标记错误。假设它是一个正常的、非空的文件,且将扩展名更正后可以正常使用,那么,如何判断它是哪种类型的文件?
使用文件签名来判断实际文件类型,又称magic numbers
或 Magic Bytes
。关于文件签名介绍,参考List of file signatures
Magic Number:
1 | public class MimeType |
摘录部份常用文件HEX签名,来源GCK’S FILE SIGNATURES TABLE
十六进制签名 | ASCII 签名 | |
---|---|---|
文件扩展名 | 文件描述 | |
50 4B 03 04 | PK.. | |
ZIP | PKZIP archive file (Ref. 1 Ref. 2) Trailer: filename 50 4B 17 characters 00 00 00 Trailer: (filename PK 17 characters …) Note: PK are the initals of Phil Katz, co-creator of the ZIP file format and author of PKZIP. |
|
ZIP | Apple Mac OS X Dashboard Widget, Aston Shell theme, Oolite eXpansion Pack, Opera Widget, Pivot Style Template, Rockbox Theme package, Simple Machines Forums theme, SubEthaEdit Mode, Trillian zipped skin, Virtual Skipper skin |
|
APK | Android package | |
JAR | Java archive; compressed file package for classes and data | |
KMZ | Google Earth saved working session file | |
KWD | KWord document | |
ODT, ODP, OTT | OpenDocument text document, presentation, and text document template, respectively. | |
OXPS | Microsoft Open XML paper specification file | |
SXC, SXD, SXI, SXW | OpenOffice spreadsheet (Calc), drawing (Draw), presentation (Impress),and word processing (Writer) files, respectively. | |
SXC | StarOffice spreadsheet | |
WMZ | Windows Media compressed skin file | |
XPI | Mozilla Browser Archive | |
XPS | XML paper specification file | |
XPT | eXact Packager Models |
javascript在线计算:
文件签名表格:
GCK’S FILE SIGNATURES TABLE
参考资料:
Magic number
List of file signatures
拓展阅读:
byte为什么要与上0xff?
C#穿透session隔离———Windows服务启动UI交互程序
一开始是因为服务器经常会出现断电、系统崩溃的情况,导致一些正常运行的winform程序在系统故障重启后,每次都需要手动登录触发事件让程序自启。然后想利用windows服务在开启时就会自启来实现开机启动Winform程序。
但是因为从Vista 开始引入了 Session 0 隔离机制,导致windows服务无法直接进行界面交互操作。
注意:
使用CreateProcessAsUser与界面交互需要Session Id >0 ,用户会话的必须存在,如果存在服务器重启、注销后,重新开机导致系统只有Session 0存在,此时服务调用后的程序是不会显示界面的。
所以到头来还是没能实现我的想法。。。淦
参考:
在早期的Windows操作系统中,在同一用户下运行的所有进程有着相同的安全等级,拥有相同的权限。例如,一个进程可以自由地发送一个Windows消息到另外一个进程的窗口。从Windows Vista开始,当然也包括Windows 7、Windows 10,对于某些Windows消息,这一方式再也行不通了。进程(或者其他的对象)开始拥有一个新的属性——特权等级(Privilege Level)。一个特权等级较低的进程不再可以向一个特权等级较高的进程发送消息,虽然他们在相同的用户权限下运行。这就是所谓的用户界面特权隔离(User Interface Privilege Isolation ,UIPI)。
UIPI的引入,最大的目的是防止恶意代码发送消息给那些拥有较高权限的窗口以对其进行攻击,从而获取较高的权限等等,在计算机系统中,这却是一种维护系统安全的合适方式。
对于简单的交互,服务可以通过WTSSendMessage 函数,在用户Session 上显示消息窗口。对于一些复杂的UI 交互,必须调用CreateProcessAsUser 或其他方法(WCF、.NET远程处理等)进行跨Session 通信,在桌面用户上创建一个应用程序界面。
解决思路是:window service创建一个和与当前登陆用户可以交互的进程,这个进程运行在admin权限下,能够调起应用程序的UI
具体的做法是:widow service复制winlogon.exe进程句柄,然后通过调用api函数CreateProcessAsUser()以winlogon.exe权限创建新进程,新创建的进程有winlogon.exe的权限(winlogon.exe运行在system权限下),负责调用程序。
作者原文:
First, we are going to create a Windows Service that runs under the System account. This service will be responsible for spawning an interactive process within the currently active User’s Session. This newly created process will display a UI and run with full admin rights. When the first User logs on to the computer, this service will be started and will be running in Session0; however the process that this service spawns will be running on the desktop of the currently logged on User. We will refer to this service as the LoaderService.
Next, the winlogon.exe process is responsible for managing User login and logout procedures. We know that every User who logs on to the computer will have a unique Session ID and a corresponding winlogon.exe process associated with their Session. Now, we mentioned above, the LoaderService runs under the System account. We also confirmed that each winlogon.exe process on the computer runs under the System account. Because the System account is the owner of both the LoaderService and the winlogon.exe processes, our LoaderService can copy the access token (and Session ID) of the winlogon.exe process and then call the Win32 API function CreateProcessAsUser to launch a process into the currently active Session of the logged on User. Since the Session ID located within the access token of the copied winlogon.exe process is greater than 0, we can launch an interactive process using that token.
参考:
交互式服务
C#开发Windows服务详细流程
C#穿透session隔离———Windows服务启动UI交互程序
Subverting Vista UAC in Both 32 and 64 bit Architectures
windows服务启动winform程序不显示UI问题解决
原因:
xp系统的用户和window service运行在一个session下,在xp以后,windows系统改变了用户会话管理的策略,window service独立运行在session0下,依次给后续的登录用户分配sessionX(X =1,2,3…),session0没有权限运行UI。所以在window xp以后的系统下,window service调用有UI的application时只能看到程序进程但不能运行程序的UI。
参考:
C# windows服务启动winform程序不显示UI问题解决
How can a Windows service execute a GUI application?
穿透Session 0 隔离(二)
使用互斥锁,实现只有一个程序
本来是想在服务器上实现服务器崩溃或者更新后,可以自动启动winform程序,但是以下方法还是需要有用户登录进去。
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
如果需要针对个人账户进行配置:Win+R
输入命令shell:startup
,会直接弹出启动项对应的目录,然后像前面方法一样把应用程序快捷方式复制到启动目录
在Windows操作系统下,主要有2个文件夹和8个注册表键项控制程序的自启动,通过修改“Run”键值实现自启动程序是比较常见的方法。
具体的位置是:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run
在知道注册表中自启动位置所在后,只需要将需要启动的程序路径添加至指定路径中就可以实现开机自启动功能。
1 | /// <summary> |
SystemHelper.cs
参考自:C# winform程序实现开机自启动,并且识别是开机启动还是双击启动
1 | public sealed class SystemHelper |
运行环境
Win10
.NET Framework4.5
VS2019
注册表地址
使用代码修改注册表的方式,如果需要查看注册信息,需要确认程序是32-bit还是64-bit。
32位,查看地址为 :HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVers ion\Run
64位,查看地址为 :HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
操作系统 | 64位程序访问的注册表 | 32位程序访问的注册表 |
---|---|---|
64位系统 | HKEY_LOCAL_MACHINE\SOFTWARE | HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node |
32位系统 | - | HKEY_LOCAL_MACHINE\SOFTWARE |
参考资料:
以管理员权限打开程序:
参考资料:
Update your browser to view this website correctly.&npsb;Update my browser now