shell_3

提供 SE_ERR_XXX 之类的错误代码是为了兼容 ShellExecute使用 GetLastError可以获得更详细的错误信息。返回值可以使下列之一:

 

Error

Description

ERROR_FILE_NOT_FOUND

指定文件不存在

ERROR_PATH_NOT_FOUND

指定路径不存在

ERROR_DDE_FAIL

动态数据交换 (DDE) 处理失败

ERROR_NO_ASSOCIATION

没有与制定文件名扩展对应的应用程序

ERROR_ACCESS_DENIED

访问指定文件被拒绝

ERROR_DLL_NOT_FOUND

无法找到运行应用程序所必须的库文件

ERROR_CANCELLED

这个函数要求用户提供更多其他信息(译注:比如弹出对话框),但请求用户被取消了

ERROR_NOT_ENOUGH_MEMORY

没有足够的内存来执行操作

ERROR_SHARING_VIOLATION

共享违规发生了

Windows 95/98/Me: ShellExecuteEx 为 Microsoft Layer for Unicode (MSLU) 所支持。为了使用这个函数,必须添加额外的文件到应用程序中去,请参考: Microsoft Layer for Unicode on Windows Me/98/95 Systems .

 

函数信息:

 

Minimum DLL Version

shell32.dll version 3.51 or later

Custom Implementation

No

Header

shellapi.h

Import library

shell32.lib

Minimum operating systems

Windows NT 4.0, Windows 95

Unicode

Implemented as ANSI and Unicode versions

 

 

 

下面举例说明如何使用这个函数, executePackage 这个函数用来执行某个应用程序。

1. bool  executePackage( LPCWSTR  fileName,  LPCWSTR  args,  LPCWSTR  baseDir,  bool  wait)  

2. {  

  1. 3.     SHELLEXECUTEINFOW sei = { sizeof (SHELLEXECUTEINFOW) };  
  2. 4.   
  3. 5.     sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;  
  4. 6.   
  5. 7.     sei.lpFile = fileName;  
  6. 8.     sei.lpParameters = args;  
  7. 9.     sei.lpDirectory = baseDir;  
  8.   
  9.     if  (!ShellExecuteExW(&sei)) {  
  10.         return   false ;  
  11.     }  
  12.   
  13.     if  (wait) {  
  14.         HANDLE  hProcess = sei.hProcess;  
  15.         if  (hProcess != 0) {  
  16.             WaitForSingleObject(hProcess, INFINITE);  
  17.             CloseHandle(hProcess);  
  18.         }  
  19.     }  
  20.   
  21.     return   true ;  
  22. }  

 

查看评论

* 以上用户言论只代表其个人观点,不代表优快云网站的观点或立场

个人资料


okadler0518

  • 访问:49445次
  • 积分:1963分
  • 排名:第2559名
  • 原创:134篇
  • 转载:57篇
  • 译文:1篇
  • 评论:36条

文章搜索

窗体顶端

 

窗体底端

文章分类

文章存档

阅读排行

评论排行

推荐文章

最新评论

mapeijie888: 够清楚 .................遇见你专家了

gejjun: 装了虚拟网卡就有了。

okadler0518: 绘制图像,必须要的是刷新。WM_PAINT就是这个功能。图片的绘制有3-4中方法,也就是函数不一样而...

Wang471981125: 除了这种机制 还有其他的方法来进行图像的绘制吗?

okadler0518: gdc = BeginPaint (hwnd, &ps);gdc = GetDC (hwnd...

okadler0518: 2. WM_PAINT里面,最好用BeginPaint。我一开始都说很清楚了。

okadler0518: 1. break,是switch的循环跳出语句。是c/c++基础。

shmylm4201: 想问一下,假如我写一个WM_PAINT:break;这表示什么意思?还有我想在一个窗口中播放rtsp...

shangwei97: 正要做这方面的工作。谢谢

leewckk:

 

关机

<think>好的,我现在需要帮助用户解析proto_shell_notify函数的含义。首先,我得仔细看一下用户提供的代码,并理解每个部分的作用。用户可能对这段代码的结构和功能不太清楚,所以我要逐步分解,确保每个部分都解释到位。 首先,函数定义是static int proto_shell_notify,参数是proto和attr。static关键字说明这个函数只在当前文件可见,可能属于某个模块或协议的实现。参数proto应该是指向协议状态的指针,attr可能是传递的数据属性。 接下来,函数内部声明了state和tb数组。state的类型是struct proto_shell_state指针,这里用了container_of宏,这说明proto_shell_state结构体内嵌了interface_proto_state。container_of的作用是通过成员地址找到整个结构体的地址,所以state变量实际上指向包含proto成员的proto_shell_state实例。这一步可能涉及到Linux内核中常见的结构体内嵌手法,用于实现类似面向对象的结构关系。 然后,blobmsg_parse函数被调用,解析attr数据到tb数组。这里用了notify_attr作为策略,__NOTIFY_LAST作为属性数量。如果解析后发现缺少NOTIFY_ACTION属性,函数返回无效参数错误。这说明NOTIFY_ACTION是必须的,用于后续的分支处理。 接下来的switch语句根据NOTIFY_ACTION的值执行不同的操作。每个case对应不同的动作,比如0到7分别调用不同的处理函数。例如,case 0处理更新链接,case 1执行命令,case 2终止命令等等。每个case返回对应的处理函数的结果,而默认情况返回无效参数。 用户可能需要了解每个case对应的具体功能,以及整个函数在协议处理中的作用。可能的疑问包括:container_of的作用,blobmsg_parse如何解析数据,每个case对应的业务逻辑是什么,以及返回值的意义。 需要确认是否有错误的理解点。例如,container_of是否正确使用,blobmsg_parse的参数是否正确,以及每个case的处理函数是否合理。同时,要确保解释清晰,帮助用户理解函数如何根据不同的动作分发到不同的处理逻辑,以及错误处理的方式。 最后,整理这些分析步骤,用中文结构清晰地呈现,确保用户能够逐步理解函数的各个部分及其整体功能。</think>以下是对`proto_shell_notify`函数的逐层解析: --- ### **函数定义** ```c static int proto_shell_notify(struct interface_proto_state *proto, struct blob_attr *attr) ``` - **作用**:处理协议层通知事件的分发函数 - **关键特性**: - `static`:表明函数仅在当前文件可见 - 返回`int`类型的状态码(如UBUS状态码) - 参数`proto`:协议状态机指针 - 参数`attr`:二进制属性数据块 --- ### **核心逻辑分解** #### **1. 状态初始化** ```c struct proto_shell_state *state; struct blob_attr *tb[__NOTIFY_LAST]; state = container_of(proto, struct proto_shell_state, proto); ``` - **container_of**:通过`proto`指针反向获取其父结构体`proto_shell_state` - **设计意图**:实现类似面向对象中"从基类派生"的效果 #### **2. 数据解析** ```c blobmsg_parse(notify_attr, __NOTIFY_LAST, tb, blob_data(attr), blob_len(attr)); if (!tb[NOTIFY_ACTION]) return UBUS_STATUS_INVALID_ARGUMENT; ``` - **blobmsg_parse**:将二进制数据`attr`解析到属性表`tb` - **安全校验**:必须包含`NOTIFY_ACTION`字段,否则返回参数错误 #### **3. 动作分发** ```c switch(blobmsg_get_u32(tb[NOTIFY_ACTION])) { case 0: return proto_shell_update_link(...); // 更新链路状态 case 1: return proto_shell_run_command(...); // 执行shell命令 case 2: return proto_shell_kill_command(...); // 终止正在运行的命令 case 3: return proto_shell_notify_error(...); // 错误通知处理 case 4: return proto_shell_block_restart(...); // 阻止服务重启 case 5: return proto_shell_set_available(...); // 设置可用性状态 case 6: return proto_shell_add_host_dependency(...); // 添加主机依赖 case 7: return proto_shell_setup_failed(...); // 标记初始化失败 default: return UBUS_STATUS_INVALID_ARGUMENT; // 无效动作码 } ``` - **设计模式**:典型的命令模式实现,通过动作码解耦不同操作 - **扩展性**:预留0-7共8种操作类型,新增功能只需扩展case分支 --- ### **关键数据结构** ```c struct proto_shell_state { struct interface_proto_state proto; // 基础协议状态 // 可能包含shell相关私有状态: // - 正在运行的进程PID // - 网络接口配置 // - 错误计数器等 }; ``` --- ### **典型应用场景** 1. **网络接口状态变更**(如UP/DOWN事件) 2. **外部命令触发**(通过ubus调用执行脚本) 3. **依赖管理**(控制服务启动顺序) 4. **错误恢复机制**(失败时阻止无限重启) --- ### **返回值说明** | 返回值 | 含义 | |-------------------------------|---------------------| | UBUS_STATUS_INVALID_ARGUMENT | 参数缺失或非法动作码 | | UBUS_STATUS_OK | 操作成功(由子函数返回) | | 其他错误码 | 具体操作失败原因 | --- ### **代码设计亮点** 1. **松耦合**:通过动作码分离不同操作逻辑 2. **状态隔离**:每个操作函数仅处理自身状态 3. **二进制安全**:使用blobmsg处理二进制数据流 4. **类型安全**:通过`container_of`实现类型安全的继承
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值