ζ∽∑∏∞ψ

cedricporter -- [ QQ: 414112390 ]

无聊之作 -- 延迟运行其他程序de程序 (C++版)

// By: Cedric Porter [Stupid ET]
// QQ: 414112390    Q群:7196588
// 功能:运行后延迟运行其他程序,例如开机要运行一堆东西的时候就靠他了
// 用Win32编译方式来编译,就可以在后台运行了 
/* 读的文件格式     :    延迟时间 (单位:毫秒) 要运行的程序的路径 
1000 notepad
500 calc
2000 e:\Program Files\Tecent\QQ\QQ.exe
*/

// 程序超烂而且我太懒了.就注释那么多了..仅供交流..
// 因为贴在博客上格式有点变形。所以请复制到VC下,再全选,接着按下Alt+F8格式就整齐了 

#include 
<windows.h>
#include 
<fstream>
#include 
<cstring>
#include 
<cstdlib>

using namespace std;

struct PARAM
{
    unsigned 
long delayTime;
    
string ExePath;       
}
;

unsigned 
long InputHandle();
DWORD WINAPI ThreadProc(PVOID param);

int main()
{     
    Sleep(InputHandle()
+2000);     // 主线程暂停等待其他线程运行完毕 

    
return 0;
}


unsigned 
long InputHandle() //处理 
{
    ifstream inf(
"run.log"); //存放要运行的程序的列表 
    char temp = 0;
    
string    str_delay = "",        // 存放 
        str_ExePath = "";

    unsigned 
long delayTime = 0, MaxTime = 0;
    
bool IsTime = true, next = false;

    inf.
get(temp);

    
while (!inf.eof())    // 判断是否到列表文件尾部 
    {  
        
if (temp == 10 || temp == 13)     // 判断是否为回车或换行,如果是,则进行处理 
        {   
            inf.
get(temp);
            
if (str_ExePath == "")
                
continue;
            IsTime 
= true
            next 
= true;

            PARAM
* param = new PARAM;
            param
->delayTime = delayTime;
            param
->ExePath = str_ExePath; 
            HANDLE handle 
= CreateThread(NULL, 0, ThreadProc, (PVOID)param, 0, NULL);
            CloseHandle(handle); 
            
//Sleep(1);

            
if (MaxTime < delayTime)
                MaxTime 
= delayTime;
            str_ExePath 
= "";
            str_delay 
= "";
            delayTime 
= 0;
            
//cout << str_ExePath << endl;   
            continue;
        }

        
else if (temp == ' ')
        
{
            
if (IsTime)
            
{
                delayTime 
= atoi(str_delay.c_str());  
                IsTime 
= false;
                next 
= false;
                inf.
get(temp);    
                
//cout << delayTime << endl;    
                continue
            }

            
if (!next)
                str_ExePath 
+= ' ';

        }

        
else
        
{
            
if (IsTime)   
                str_delay 
+= temp;
            
else
                str_ExePath 
+= temp;
        }


        inf.
get(temp);
    }


    
return MaxTime;    // 返回要延迟的最长时间 
}


DWORD WINAPI ThreadProc(PVOID param)    
// 延缓运行其他程序的线程 
{
    unsigned 
long delayTime = ((PARAM*)param)->delayTime;
    
string ExePath = ((PARAM*)param)->ExePath;
    delete param;

    
//MessageBox(NULL, ExePath.c_str(), "a", 0);
    
//e:\Program Files\Tencent\QQ\QQ.exe

    Sleep(delayTime);
    WinExec(ExePath.c_str(), SW_SHOW);
    
//WinExec("e:\\Progra~1\\Tencent\\QQ\\QQ.exe", SW_SHOW);

    
return 0;
}
 


//湛江二中 华亮

posted on 2009-08-13 11:38 Stupid ET 阅读(2131) 评论(19)  编辑 收藏 引用 所属分类: Language

评论

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 11:50 pear_li

想法很可爱
编程意识不错,handle关闭的很及时
但是winexec这种东西少用  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 13:17 OwnWaterloo

@pear_li
winexec怎么了?  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 13:36 OwnWaterloo

> Sleep(InputHandle()+2000); // 主线程暂停等待其他线程运行完毕
严格给的说, 要用 WaitForMultipleObjects。
如果人品非常差, 延迟2秒还是有主线程先结束的可能, 因为调度顺序是未知的。

> 因为调度未知
从CreateThread开始, 到次线程Sleep 之间会有未知时间的间隔。
所以, 传给次线程的, 不应该是delay, 而是awake_time。
次线程在Sleep前一刻, 根据awake_time和current_time, 计算Sleep多久。
这样, 精度就不受CreateThread,到Sleep之间那段未知时间的影响。
如果精度还要提高, 可以用WaitableTimer。

> CreateThread
在vc上用_beginthreadex代替。 dev c++如果是用的mingw, 也有这个函数。


最后一点………… 其实偷懒的话去查AT的用法 ……
run -> cmd -> at /?
直接写个bat文件:
at xxxx notepad
at yyyy calc
....

而不用写一个配置文件, 然后用一个程序去读, 再执行……
功能差不多, 精度可能低一些。  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 13:37 OwnWaterloo

高中生?  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 13:53 OwnWaterloo

@OwnWaterloo
哦, 原来是个backward compatibility函数……  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 15:12 Stupid ET

呃...曾经是高中时写的...从我的百度空间移过来的...@OwnWaterloo
  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 15:19 11

典型的滥用多线程的例子。 直接读取配置来一个排序, 以一个小的粒度检查时间来运行要运行的程序就可以了。  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 15:20 Stupid ET

哇..佩服佩服.....@OwnWaterloo
  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 15:21 Stupid ET

哦。恍然大悟,O(∩_∩)O谢谢...@11
  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 18:19 OwnWaterloo

@Stupid ET
这些代码是你高中写的?? 牛……

我觉得这思路挺好, 将n个任务分到不同线程, 然后用Sleep的方式通知OS。

谁知道OS里面会不会有:
“来一个排序, 以一个小的粒度检查时间来运行要运行的”线程
这种调度算法呢?

谁知道OS会不会比ls某位的算法更差呢?

谁知道windows下的创建线程开销会比ls某位的算法高呢?


这些都不知道, 要测也不方便。

但是, 编码简单很多~~~ 同时线程间的同步也很方便处理。
KISS~~~  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-13 21:52 Stupid ET

@OwnWaterloo
小菜我刚刚高中毕业,以后多多指教哦...  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 08:32 guest

1:WinExec 返回是进程第一次调用GetMessage或者一个超时,从这点出发,还是不用WinExec为妙
2:博主还没处理空格符带来的问题,WinExec填写的参数是错误的,例如有个程序是e:\Program.exe,你的QQ就被病毒给劫持了。
3:主线程应该调WaitForMultipleObjects
4:用CreateProcess或者ShellExcute,前者可以顺带挂起进程,后者可以直接运行脚本或者打开文件。
5:用脚本都可以实现的功能。  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 09:35 11

to OwnWaterloo:
你真的以为线程同步比一个循环来得更简单么? 很明显的,启动那些程序不需要同时执行,既然可以顺序执行, 为什么不顺序执行呢?我以为代码是越简单越好。

这个里面只需要一个 for或while循环就可以完成

//任务列表按执行先后排序
//index = 0;
//n = 任务的个数
while(index < n)
{
//检查 index 处的任务是否到了执行时间
if(...)// 没有到
{
Sleep(10); //10毫秒,可以根据需要的精度调整此检查频率
}
else
{
// 到了执行, 然后递增 index 进入下一次循环
}
}
// 全部执行完就自动退出程序

先不谈线程开销这类的, 这个可读性不是和要执行的任务更一致么?

  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 11:00 Stupid ET

@11
好多牛人....
  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 12:03 OwnWaterloo

@11
@11
>Sleep(10); //10毫秒,可以根据需要的精度调整此检查频率
嘿嘿, 是不是我需要更高精度的时候, 应该Sleep(5); ???

你看看这个:
999...999 a_long_delay_work.exe

还觉得你那个方法“效率高”?
你想想"可以根据需要的精度调整此检查频率"这句话, 当需要的精度要求达到极限时, 比如Sleep(0); 那个while是不是一个"忙等"?
你以为Sleep没有开销吗? 还Sleep(10)呢, 哈哈哈。


你的代码简单吗? 全都是伪代码。
而且我也说了, OS调度里面, 这些代码都有, 你老人家何苦要去和它争呢?
就这Sleep(10) , 还争什么呢争……

你这方案, 至少得算出到下一个任务开始前, 应该大致Sleep多久, 它才不算一个忙等。

-------- --------
而且, 这方案还必须是“先得到所有任务”, 再跑这个半死循环, 才可以。
如果需要再跑半死循环的中途, 新建定时任务呢?
这需求很常见, 很多类似“记事簿”的软件都要提供这功能, 而且是随时插入新的任务。

显然, 你必须至少要开2个线程了, 1个用于用户输入, 1个用来跑半死循环。
“任务队列”现在被2线程共享, 又需要加锁来同步。
这就是我说的, 自己调度会造成编码复杂的原因, 懂?


别人的方案有何优势与劣势?
如此多的方案,它们各自何种情况下是最佳方式?
想过没? 同学?
不要想都不想——如果Sleep(10)就是你想的结果, 那我真没什么必要和你继续说下去了……——就随便扣个帽子, 你以为能显示出你很能吗?  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 13:21 passing

@OwnWaterloo
淡定淡定
不要折腾  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 14:24 11

设计根据需求而定, 这个程序明显是不需要运行中提供输入输出的。只所以用伪代码只是为了说明思路。if的前面省略了更新时间标志的代码,我以为你会知道。

以固定的时间间隔来等是有效率上的问题(应该等待下一个到这一个的间隔),但是就这个应用来说根本用不到很大的精度。 你也说了,多线程中操作系统也需要这样的操作,难道你觉得有几个任务要执行就开几个线程来等待比一个线程的等待更高效?  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-14 15:40 OwnWaterloo

@11
> 但是就这个应用来说根本用不到很大的精度

扯谈!

那可不可以说“就这个应用根本不需要考虑效率”?
使用多线程(线程池都免了)的效率完全足够, 并且——我一直强调的——它编码简单, 充分利用"OS已经实现的调度机制",而不是自己重复去发明一套弱小的调度功能。


一上来就抛出一句“典型滥用xxx”, 提出一个所谓的解决方案。
典型的“什么事都想靠自己解决”的初级程序员作法。
  回复  更多评论   

# re: 无聊之作 -- 延迟运行其他程序de程序 (C++版) 2009-08-15 15:45 Stupid ET

其实这个程序只是当时刚刚接触多线程这样东西时来应用一下多线程...没想到引发那么多争论..........感慨感慨...  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理