Wednesday, November 7, 2012

【系统安装】封装自己的c盘到WIM

WIM简介
=============================================
WIM是什么?WIM全名为Windows Imaging Format,是微软从Vista开始就用在Windows Installation的~ 安装过xp的都懂,如果不靠第三方软件比如ghost,安装速度是非常非常慢的~ Vista系统体积比XP大好多倍,难道要让vista安装用上一天的时间?为了解决这个问题,微软推出了一个比ghost更好的安装方式,就是WIM~ Vista我没安装过,不敢乱说,但是被我用usb来安装了n次的Win7下在Expanding Files那边基本10分钟搞定,然后5分钟来完成安装,速度绝对比xp的安装方法快很多~ 个人觉得WIM基本可以代替Ghost了~

需注意事项
=============================================
- 这个教程需要GImageX 2,请点我下载(建议把GImageX.exe放在D盘,以方便使用)
- 虽然已经经过测试,但依然无法保证无风险,如果你觉得你最近运气不好、电脑伤不起、是小白中的小白,本人劝你三思而后行。由此教程导致的任何损失本人恕不复制。
- 本教程需要基本的命令行提示符(CMD)知识,要会使用cd命令(转换目录)

已知问题
=============================================
- 貌似Windows Setup会自作多情,会自动把你的System Locale变成English,UTC会变成-8,输入法需要自己再添加~

切入正题
=============================================
1. 首先,请先复制Install.wim到一个地方,然后重启,在出现Windows加载logo前请按F8,然后选择Repair Your Computer。
2. 然后你会被要求要你输入你的用户密码那些,点OK后会看到一个窗口,请点击Open Command Prompt
3. 然后,请在cmd用cd命令转到你GImageX.exe的目录,然后打GImageX.exe打开GImageX软件~
4. 请跟着这张图片操作:
5. 等待封装完毕,等待时可以祈祷封装成功 xD~
6. 关闭所有窗口,电脑将会重启,你的wim已经大功告成了,此时你只需要覆盖那install.wim到 安装盘的sources文件夹内~ 如果提示空间不够,但明明是够的,可以先删除sources文件夹内的install.wim,再复制~

最后附上自己成功的图图,然后祝大家封装顺利~







Monday, October 29, 2012

[原创] Async Sub 和 Sub 的分别(Metro编程)


简单来说,Async Sub就好像是在 子线程 运行的Sub,比较适合那种需要时间的代码。在Async Sub里,所有的代码都不会等 执行 完了才继续,除非你加上Await在代码的前面。

拿个代码做例子:

Async Sub AsyncTest()
Txtblock1.Text = “现在延时3
Threading.Tasks.Task.Delay(3000) ‘延时3
Txtblock1.Text = “延时完成”
End Sub

当你输入以上代码,你会发现VS2013会给你一个警告:

This async method lacks 'Await' operators and so will run synchronously. Consider using the 'Await' operator to await non-blocking API calls, or 'Await Task.Run(...)' to do CPU-bound work on a background thread.

其实你可以把这个警告看成:要注意哦,你的Async方法里没有Await哦,所有的代码都不会等待的哦。也就是说,你的延时代码也将无效哦~

如果你坚持不信,并编译运行,你会发现,你的 延时代码 真的没有效了,直接出现“延时完成”。

那么,要如何解决呢?很简单,在Threading那行的最前端加个Await就行了~

代码将会变成:

Async Sub AsyncTest()

Txtblock1.Text = “现在延时3

Await Threading.Tasks.Task.Delay(3000) ‘延时3

Txtblock1.Text = “延时完成”

End Sub

再次运行,你会发现你的 延时代码 有效了!而且,不会导致整个程序hang掉!这就是使用Async的好处!

Friday, October 19, 2012

【原创】在VB.NET中使用 SendMessage API 发送信息,与接受信息


今天,我要为大家讲解,如何在vb.net中使用SendMessage API,来发送信息,并Overrides那个WndProc函数来接受信息

首先请在新建一个Class,代码:

Imports System.Runtime.InteropServices

Public Class Form1

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure COPYDATASTRUCT
        Public dwData As IntPtr
        Public cbData As IntPtr
        Public lpData As IntPtr
    End Structure

    Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As IntPtr, ByRef lParam As COPYDATASTRUCT) As IntPtr
    Public Const WM_COPYDATA As Integer = &H4A

End Class


—— 发送信息 篇 ——

首先,我们要得到一个 句柄 IntPtr,变量名为hWnd(Me.Handle就是一个例子)
过后我们New一个COPYDATASTRUCT,变量名为CDS

CDS.dwData不是很清楚是什么来的,听说是自定义资料,个人觉得放intptr.zero就好了
代码:CDS.dwData = IntPtr.Zero

CDS.lpData 是我们要发生的信息,在这里我们需要用Marshal.StringToHGlobalAuto来转换Managed String成Unmanaged memory
代码:CDS.lpData = Marshal.StringToHGlobalAuto("message here")

CDS.cbData 则是指定memory大小
代码:CDS.cbData = New IntPtr(Marshal.SystemDefaultCharSize * Msg.Length)

然后就是用API来发送信息
代码:SendMessage(hWnd, WM_COPYDATA, 0, CDS)

—— 接受信息 篇 ——

如果你还记得我们SendMessage的代码,SendMessage(..., ..., ..., lParam as COPYDATASTRUCT)
你应该会猜到,其他程序发送给我们的CDS其实就在m.LParam。
可是,它是CDS,是一个结构体(Structure),不能直接使用,我们需要“还原”那个CDS出来。
我们先New一个COPYDATASTRUCT,变量名为CDS。
然后,我们使用m里面的一个函数,叫GetLParam,它可以让我们转换LParam到另一个 类型。
转换到我们要的COPYDATASTRUCT类型后,就可以给CDS赋值了。
代码:CDS = m.GetLParam(CDS.GetType)
但毕竟这样得到是Object,如果要更正式点,可以加个CType
代码:CDS = CType(m.GetLParam(CDS.GetType), COPYDATASTRUCT)
好了,得到了CDS了,现在我们可以通过CDS的lpData,来得到 信息。
信息 发过来时是由String变成Unmanaged Memory发来的,所以我们现在要转回去。
又要麻烦下Marshal了~ 这次我们用的是PtrToStringAuto,得提供两个参数,一个是Unmanaged Memory,一个是Memory Size
代码:Dim Str as string = Marshal.PtrToStringAuto(cds.lpData, cds.cbData.ToInt32 \ Marshal.SystemDefaultCharSize)
现在那 信息 就在 Str 变量里面了~
如果你要指定返回值,可以给m.Result赋值~
代码:m.Result = New IntPtr(777)

示例代码:

Imports System.Runtime.InteropServices

Public Class Form1

    <StructLayout(LayoutKind.Sequential)> _
     Public Structure COPYDATASTRUCT
        Dim dwData As IntPtr
        Dim cbData As IntPtr
        Dim lpData As IntPtr
    End Structure

    Public Declare Auto Function SendMessage Lib "user32.dll" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal wMsg As Int32, _
    ByVal wParam As IntPtr, ByRef lParam As COPYDATASTRUCT) As IntPtr
    Public Const WM_COPYDATA As Integer = &H4A

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        txtMeHandle.Text = Me.Handle
    End Sub

    Private Sub btnNewInstance_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNewInstance.Click
        Shell(Application.ExecutablePath, AppWinStyle.NormalFocus)
    End Sub

    Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        Dim hWnd As IntPtr 'for the target handle
        'First we need to know the environment is 32bit or 64bit
        If IntPtr.Size = 4 Then 'is 32 bit
            Dim hWndInt As Integer 'for storing the parsed integer
            If Integer.TryParse(txtTargetHandle.Text, hWndInt) Then
                hWnd = New IntPtr(hWndInt)
            Else
                MsgBox("The handle you entered was unable to parse, please make sure it's number-only.")
                Return
            End If
        ElseIf IntPtr.Size = 8 Then 'is 64 bit
            Dim hWndLong As Long ' for storing the parsed long
            If Long.TryParse(txtTargetHandle.Text, hWndLong) Then
                hWnd = New IntPtr(hWndLong)
            Else
                MsgBox("The handle you entered was unable to parse, please make sure it's number-only.")
                Return
            End If
        End If
        'Then, we need to have a COPYDATASTRUCT, for storing the data we wanted to send
        Dim CDS As New COPYDATASTRUCT
        CDS.dwData = IntPtr.Zero
        'CDS.lpData <- it's actually unmanaged memory, so if we want to send string, we must use a function in Marshal 
        'to convert our string to unmanaged memory.
        CDS.lpData = Marshal.StringToHGlobalAuto(txtMsgToSend.Text)
        'CDS.cbData <- it's represent the memory size. Any type of data, even like string, also required a certain memory size.
        'So we should make some math, tell the API, how many memory we want for our string
        CDS.cbData = Marshal.SystemDefaultCharSize * txtMsgToSend.Text.Length
        'OK, now it's time for us to use the API, as we prepared all of the data that API required
        ' If you just wanna send message, then:
        ' SendMessage(hWnd, WM_COPYDATA, 0, CDS)
        ' If you wanna get the "response" from the target window too, then:
        ' Dim Result as IntPtr = SendMessage(hWnd, WM_COPYDATA, 0, CDS)
        Dim Result As IntPtr = SendMessage(hWnd, WM_COPYDATA, 0, CDS)
        MsgBox("Target window give back this IntPtr: " & Integer.Parse(Result))
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        MyBase.WndProc(m)
        If m.Msg = WM_COPYDATA Then
            Dim CDS As New COPYDATASTRUCT
            CDS = CType(m.GetLParam(CDS.GetType), COPYDATASTRUCT)
            Dim Msg As String = Marshal.PtrToStringAuto(CDS.lpData, CDS.cbData.ToInt32 \ Marshal.SystemDefaultCharSize)
            Dim Ans As String = InputBox("Received a message, message content:" & vbCrLf & Msg & vbCrLf & vbCrLf & "Please enter the result (number-only): ", "I got a message!")
            Dim mResult As Integer
            If Integer.TryParse(Ans, mResult) = False Then
                MsgBox("You entered a non-number-only value, the result will be 0")
            Else
                m.Result = New IntPtr(mResult)
            End If
        End If
    End Sub

End Class



看到了吧?其实 接受信息 和 发送信息 的方法是一样的,只不过倒转过来罢了~
可是对于新手,尤其是曾经的我,在没有相关资料辅助下是很难明白的,故写此贴。
由于本人水平有限,可能有些地方写得不对,本人的建议是,先读了此贴,有个概念,再去读其他高手的帖,希望可以让你更明白~

Saturday, October 13, 2012

【图解】Msgbox VS Messagebox.show

一直以为我以为Msgbox和Messagebox.show没什么分别,觉得自己vb.net直接支持msgbox(C#可以通过导入microsoft.visualbasic来使用msgbox)是很光荣的事,直到今天我才知道我后知后觉……
如果你要YesNo类型但又有Question图标的 对话框 时,你就知道为何messagebox.show会更好了……

Friday, October 5, 2012

[吐糟] 吐糟下Win8的各种不满意 [part 2]

接下来,我要讲的是 传统桌面

===== Win8传统桌面 —— 主题 =====

不可否认,Aero主题和Metro混搭在一起时,感觉会很怪,所以Win8正式版的主题,再也不是Aero了,而是我做梦都没想到的Metro主题……

Windows 8 正式版 默认主题
标题栏的发光字效果已不再
这个改变,使得很多使用aero作为界面皮肤的软件,比如魔方3(早期版本),会变得很怪,因为发光字效果已经被取消了。不过这样也好,起码整个主题看起来比较适合metro。

对于此主题,我个人有我喜欢的地方,也有我不爽的地方。
先讲我喜欢的地方吧~

1. 从vista开始期待到现在的 菜单 样式!我承认我特别喜欢office xp的 菜单 样式~
有用过Office XP的人都会对Win8的 菜单 样式 有种熟悉的感觉
这就是我理想中的 简洁美观!

2. 没有aero效果,没有大大的开始按钮,更适合已启用 小任务栏按钮 (small taskbar button) 的任务栏

个人认为,Aero在 大任务栏按钮 下会比较好看,小任务栏按钮 还是半透明看起来更适合
没有了那个大大的开始按钮,启用 小任务栏按钮 时整个任务栏看起来更自然~
3. 窗体标题 置中

Windows Vista的前身,即Longhorn,曾经有过一个bulid,里面的主题也是这样的,那主题名称叫“Plex”
如图所示,这就是传说中的Plex主题,是否有想尝试 此bulid 的冲动?
当然,win8主题也有相当多我不爽的地方~

1. 坑爹的主题设置

无法设置窗体/任务栏是否透明
没有“高级”选项(让你选择标题栏字体那个)
好吧,其实“高级”选项我表示在vista之后就极少碰到,但是win8默认主题有个很坑爹的地方让我想发狂,想用“高级”选项改掉却没门?
那坑爹的地方就是:Tool Window标题栏
坑爹,史上哪里有这样大的Tool Window标题栏?!你看我VS2005的properties窗体变成什么样了……失去了应有的“苗条”的感觉,感觉好像在使用98下Windows Classic (large)主题……
2. 坑爹的主题配色,如果你使用太暗或者太亮的颜色……

表示这个问题从vista开始就有,不过win8貌似缓解了 任务栏 那部分的问题……

如果你选择正常的颜色……
如果你是黑暗派,我劝你还是去找个比较好的第三方主题……
这个在vista和win7下会很悲剧,任务栏的字基本看不到……
不过Win8已经缓解了这个情况,只是任务栏字体看起来没使用正常颜色那样舒服~
结论:如果微软肯提供选项在 配色 那边,让用户设置标题栏和任务栏字体的颜色/智能调整,这问题就会完美解决了……

===== Win8传统桌面 —— File Explorer =====

Windows Explorer,即 资源管理器,此名称从NT4就开始用,直到Win8,微软终于将它更名为File Explorer,即 文件管理器。Win7到Win8的Explorer改变的程度,和XP到Vista的Explorer改变的程度差不多一样,改变了非常非常多东西,不过本质没有改变,它是文件管理器的同时也是一个给用户使用的操作界面,有些恶搞批处理,就是通过杀掉explorer进程,让被恶搞的人惊慌失措,因为什么东西都没有了,只剩下桌面壁纸……

Win8文件管理器改变得最坑爹的地方,莫过于把 Command Bar 去掉,并把 Detail Pane 的位置从下端移到右端了……

1. Command Bar VS Ribbon
红色框显示的就是Command Bar
Command Bar是从Vista时代开始有的,当时命令排得不大合理。但在Win7时代时,它已经被改良到相当不错,并真的达到Command Bar的目的:方便用户使用。

可现在Win8已经没有Command Bar了,取而代之的是Ribbon。Ribbon其实是很不错的,可是,不是任何情况下,它都是那么好用……

打个比方,如果在Windows 7,要管理你的 库(Libraries),通过Command Bar很多操作几乎一键就可搞定。一键创建、一键打开 库 设置……

对于大家都习惯右键/按快捷键操作的命令,比如 复制、删除,并没有加在Command Bar里面,这使得Command Bar是那么地简洁,而且是很智能的,对于不会用到的命令会 隐藏 起来,而不是 禁用(变灰色)。如果你坚持要有 复制文件 这些命令在你的Command Bar上,可以根据网上的教程来做到~

换句话说,Command Bar其实就是针对某个情况下,显示你会用到的特殊命令,比如在 库 下,你会看到 库 的相关命令,如果在 我的电脑 下,你也会看到相关命令,比如Control Panel(控制面板)、System Properties(系统属性)。

可在Win8,这一切已经成为神话……

Win8的文件管理器里,用的是Ribbon。根据微软的描述,貌似是为了方便以后 触屏用户的使用,减少对右键菜单的依赖,所以才换成Ribbon的。我只想说,微软这是在胡扯么,Command Bar本身的 选项大小 都很大,应该适合触屏。如果说不想 右键 而使用Ribbon,你可以将 Command Bar 作为一个选项啊,让用户可以选择啊。你现在这样子做,就是等于不理 传统PC用户 的感受,只为了 触屏用户 的好感啊~

Ribbon的确很适合 触屏,因为 触屏用户 点多一次,比起 点久久(以前用windows mobile是这样开右键菜单的,不懂现在还是不是),的确会更愿意。但是,对于鼠标用户来说,尤其是 触摸板 用户,这个让操作更不方便…… 再说,Ribbon让小屏用户很悲剧…… 占用很多空间…… 如果微软肯提供 选项,让用户选择,你用你的Ribbon,我用我的Command Bar+右键菜单,不就好了吗……

2. Detail Pane
红色框 就是 Detail Pane
这个Detail Pane,在vista和win7时都是在 资源管理器 底端的。可在Win8,却变成了在 右端……

Win8 文件管理器 的 Preview Pane是在 右端 的
真心不明白,移到 右端 有什么好处,有些人说 比较好看,但我觉得没两样……
除了,当你点击某些文件,比如图片文件时,Windows将把 这文件 尽可能多的 资料 展示在你的面前…… 这也许算是一个优点吧…… 不过对我而言,我并不需要这样多的 资料,Win7下设置Detail Pane的大小到大图标,我要的 资料 基本都有了……
图片文件 的所有资料 都展示在你的面前
突然想到,会不会是微软自己也觉得 Ribbon 太占空间,加上很多人都使用 宽屏,就把 Detail Pane移到 右端 呢?不过我可以说,这设计,绝对是 4:3比例荧幕 用户的噩梦……

好了,基本要吐糟的东西都吐完了~ 不懂大家是否消化得了我这样长的文章呢? 呵呵~

注:Win7截图是我从别的网站直接拿来的,因为我这个文章是在Win8下打出来的。

Thursday, October 4, 2012

[吐糟] 吐糟下Win8的各种不满意 [part 1]

Windows 8,是一个将于10月26日正式发售的操作系统,相信有关注的人应该都很清楚win8的主打特点,甚至已经用上了好一段时期,所以在此不多说。用了windows 8也有一段时候了,感觉对于win8的各种特性和改变都有比较清楚的了解了,所以有特别多东西想要吐糟。

首先我要讲的就是,Metro应用。

===== Metro 应用 —— 分辨率篇 =====
根据微软的描述,Metro应用
- 需要1024*768以上的分辨率来运行
- 要有1366*768以上的分辨率才能分屏(这个可以有)

原因:根据微软的分析,有大部分人都是1366*768分辨率以上的用户,所以他们觉得设置一个最低分辨率限制很有必要。以便让开发者有个标准可以跟,不用担心他的apps在1024*768以下分辨率运行时会有问题。

我的观点:小屏更需要全屏

想当年,很多游戏都是全屏的,因为当时的荧幕都是很小的,最大貌似才1024*768罢了,而且全屏可以让玩家更投入,也能让游戏运行得更流畅(对于当时来讲)。

但现在微软说,不想开发者难做,要兼顾小屏,所以就果断放弃小屏。

小屏其实更需要全屏,因为荧幕本身就很小,窗体就显得没意思,这和 为何手机不让游戏都运行在一个窗体 是同一个道理。现在微软这样做,就等于让 win8小屏用户,只能使用传统界面,那个充满窗体的界面。这是不符合逻辑的,也违背了metro应用 的意义。Metro应用 就是要让用户可以投入,可以避开乱七八糟的窗体,显示尽可能多资料的同时不让用户眼花缭乱。窗体 则比较适合多任务,大荧幕的。换句话说,越小的荧幕,越没有窗体的必要。

如果开发者不想让自己的apps在小荧幕会很丑有问题,可以开发 小屏版 啊……
由于微软想要一次通吃所有的分辨率,因此 小屏 确实是个负担。但其实这很容易解决的,给开发者搞 小屏版 和 大屏版 不就行了……

小屏版 (字体图片都比较小)- 1024*768 以下
大屏版 (字体图片都比较大)- 1024*768 以上

===== Metro 应用 —— 应用权限篇 =====
大家都知道,Windows是出了名的自由操作系统,因为只要你懂得编程,尤其是C/C++编程语言的,你可以吩咐Windows任何命令,无论是正面还是负面的。虽然Windows NT的出现缓解了这个情况,但是只要运行程序的用户是管理员,程序照样可以乱来。直到了Windows Vista,就出现了UAC,但是由于速度慢、过于频繁,很多用户,尤其是小白/追求速度的,都关掉了它。即使没有关掉,只要看到有uac提示,没胆子的就一直按no,有胆的就一直按yes,只有真的知道uac用处的会仔细看了uac提示的信息,才思考要按yes或者no。结果,uac还不是很好的方案,虽然在一定程度上防止了恶意程序乱来……

现在微软貌似开始怕了,也或者是为了Windows RT,所以开始限制多多了。首先,metro应用完全不能干涉注册表,文件读写权限非常有限,然后用户要卸载的话,metro应用一个影子都没有办法留下。咋一看很像是以前nokia/sony ericsson手机流行的java应用,很多都要用户同意,或者“证书”,然后完全没办法动到系统底层的东西。

这样做的好处是,用户可以乱乱安装apps,尽情地安装,然后不爽了可以卸载,不用怕流氓问题。但是这样会导致一点问题,比如凡是关于到系统底层的东西,都要跳去 传统桌面。问题时,微软已经开始不提倡 传统桌面 了,所以我在想,不会是微软想要学apple吧,什么 系统设置 都需要通过微软自己本身的 应用,无法通过第三方软件,否则就要 越狱…… 我个人是不希望这样的情况发生,否则Windows以后再也不是那个让人玩转的Windows,以后学Windows编程就没多大乐趣了……

还有就是,微软规定 Metro应用 只能通过 应用商店 发布,让用户安装。否则就需要用vs2012做出一个繁琐的 安装包,如果用户要安装,就要获得 开发者账号,虽然目前是可以免费获得的,但是也很麻烦…… 这样也表示,如果你要你的 Metro应用 可以在 应用商店 上架,就一定要和微软“打好关系”,至少也要保持友好的关系,否则即使你的应用可以顺利通过,恐怕在排名上也会石沉大海……

好了,以后有空再续吧……

Sunday, September 23, 2012

【C++转载好料】Visual C++启动另一个可执行程序的方案


此文章不是我写的,是转载的,为了让大家能更好地了解,我做了点改正+讲解,并已经测试,在VS2005下是没问题的,原文在:http://blog.csdn.net/weaver2007/article/details/5700312

请记得include一个头文件:windows.h

有三个API函数可以运行可执行文件:
  • WinExec(超简单易用)
  • ShellExecute(较多选项,可以获得运行的程序的hWnd(句柄))
  • CreateProcess(因为使用复杂,比较少用)
【WinExec和ShellExecute比一比】

WinExec
- 短名运行:在%path%变量里面的程序
- 返回的是 启动是否成功值(uint)
- 无法设置运行目录
- 只能打开exe/com等可执行的程序,如果是txt文件,是不会打开的
- 如果你的程序是 命令行界面的,要执行的程序也是 命令行界面的话,运行的程序会在同一个窗体

ShellExecute
- 短名运行:在%path%变量里面的程序 + 某些特别程序(比如winword.exe)
- 返回的是 被执行的程序 的实例句柄(hWnd)
- 可以设置运行目录(Working Directory)
- 对于有关联的文件/协议,比如a.txt和http://www.google.com/,是可以打开的
- 运行的程序会在新的窗体,不管是不是命令行界面

【WinExec篇】

UINT WINAPI WinExec(
  _In_  LPCSTR lpCmdLine,
  _In_  UINT uCmdShow
);
  • lpCmdLine:要执行的程序
  • uCmdShow:指明运行程序的窗体要怎样的,请参考 窗体显示方式常量
返回的东西:运行是否成功值
例子:WinExec(’Notepad.exe Readme.txt’, SW_SHOW)

【ShellExecute篇】
HINSTANCE ShellExecute(
  _In_opt_  HWND hwnd,
  _In_opt_  LPCTSTR lpOperation,
  _In_      LPCTSTR lpFile,
  _In_opt_  LPCTSTR lpParameters,
  _In_opt_  LPCTSTR lpDirectory,
  _In_      INT nShowCmd
);
● hWnd:指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句柄,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。
  ● Operation:指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参数设为NULL时,表示执行默认操作“open”。
  ● FileName:指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。
  ● Parameters:指定命令行参数,可设置为NULL。
  ● Directory:指定运行目录,可设置为NULL。
  ● ShowCmd:指定 窗体显示方式,请参考 窗体显示常量
  若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。  

【窗体显示方式常量】
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同

【CreateProcess篇】
注意:这货功能非常多,但会令人吐血(对于我这样的新手来说),如非必要强烈建议避免用这个


BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);
  • lpApplicationName 和 lpCommandLine :这个有点乱,与其说多多,不如直接这样看待:<lpApplicationName> <lpCommandLine>
比如一个运行命令:C:\Windows\System32\notepad.exe hello.txt,你可以这样:
lpApplicationName = "C:\Windows\System32\notepad.exe"
lpCommandLine = "hello.txt"
或者这样:
lpApplicationName = NULL
lpCommandLine = "C:\Windows\System32\notepad.exe hello.txt"
但是你不能这样:
lpApplicationName = "C:\Windows\System32\notepad.exe hello.txt"
lpCommandLine = NULL
如果不要参数,你就可以这样玩:
lpApplicationName = "C:\Windows\System32\notepad.exe"
lpCommandLine = NULL
或者:
lpApplicationName = NULL
lpCommandLine = "C:\Windows\System32\notepad.exe"
  • lpProcessAttributes 和  lpThreadAttributes:真心不清楚什么来的,请设置为NULL
  • bInheritHandles:决定子进程对父进程继承性,一般设为FALSE。
  • dwCreationFlags:用于标识标志,以便用于规定如何来创建新进程。点击查看相关常量
  • lpEnvironment:指向包含新进程将要使用的环境字符串的内存块,可以设置为NULL
  • lpCurrentDirectory:指定运行目录,可以设置为NULL
  • lpStartupInfo:这货很乱,我消化不来,所以请看后面的example吧……
凌晨1点了,我先睡觉了,有空再续……