windows服务程序是个好东西,尤其是你要做的软件很复杂的时候,一个模块一个模块的写,都写成服务程序,免得像一般程序的时候启动的时候要启动多个。基于这个考虑,我决定写个windows服务程序。
step1:FILE/OTHER/SERVER,建立框架;
STEP2: 新建FORM,像一般程序一样写代码。
STEP3: 安装,比如你的服务叫 STEST.EXE
再CMD窗口中键入 STEST.EXE -INSTALL
卸载的话STEST.EXE -INSTALL/U
注意:1。如果程序中用到odbc数据库,一定选用系统dns
2。服务程序调试不是很好调试,最好写入记录文件,或者先在用正常程序实现,在搬代码。
以下为原码
----------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------
// task 1:存入数据库 udisk
// task 2:刷新显示程序 127.0.0.1 :6006端口
// task 3:后台复制
// task 4:存入数据库 fdisk
//---------------------------------------------------------------------------
#include <vcl.h>
#include <Dbt.h>
#include <stdio.h>
#include "UVD_IFC.h"
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "trayicon"
#pragma resource "*.dfm"
TMainForm *MainForm;
FILE *in0,*in2;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TMainForm::WndProc(TMessage &Message)
{ bool rundll=false;
if((Message.Msg == WM_DEVICECHANGE)&&(Message.WParam==0x8000))
{ PDEV_BROADCAST_VOLUME dbvDev = (PDEV_BROADCAST_VOLUME)Message.LParam;
DWORD vn = dbvDev->dbcv_unitmask;
char si;
char pi='A';
//if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
//{ fprintf(in2,"WParam=%d, LParam=%d\r\n",Message.WParam,Message.LParam);
// }
//fclose(in2);
for (si = 0; si < 26; ++si)
{ if (vn & 0x1)
break;
vn= vn>> 1;
pi++;
}
MainForm->path.sprintf("%c",pi );
path=path+":\\"+CFGFILE;
//if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
// { fprintf(in2,"%s\r\n",path.c_str());
// fclose(in2);
// }
try
{
//..读操作表
if ((in0 = fopen(path.c_str(), "rb"))!= NULL)
{ int fi;
FHEAD fhead;
FRED fred;
String Sql;
Sql.sprintf("DELETE FROM Udisk");
//if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
//{ fprintf(in2,"%s\r\n",Sql.c_str());
// fclose(in2);
// }
MainForm->UpdateQuery->Close();
MainForm->UpdateQuery->SQL->Clear();
MainForm->UpdateQuery->SQL->Add(Sql);
MainForm->UpdateQuery->ExecSQL();
// task 1:存入数据库 udisk
fread(&fhead, sizeof(FHEAD), 1, in0);
// if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
//{ fprintf(in2,"execsql...\r\n");
// fclose(in2);
// }
for(fi=0;fi<fhead.Num;fi++)
{ fread(&fred, sizeof(FRED), 1, in0);
Sql.sprintf("INSERT INTO Udisk (No,Page,SubNo,Save,Type,Label,Path,Key0,Key1,Key2,Key3,Key4,Key5,Key6,Key7,Key8,Key9,KeyLeft,KeyRight,KeyUp,KeyDown) VALUES (%d,%d,%d,%d,%d,'%s','%s',%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
(fred.NO%10),(fred.NO/10),fred.SubNo,fred.Save,fred.Type,fred.Label,fred.Path,
fred.key[0],fred.key[1],fred.key[2],fred.key[3],fred.key[4],fred.key[5],fred.key[6],
fred.key[7],fred.key[8],fred.key[9],fred.key[10],fred.key[11],fred.key[12],fred.key[13]);
UpdateQuery->Close();
UpdateQuery->SQL->Clear();
UpdateQuery->SQL->Add(Sql);
UpdateQuery->ExecSQL();
// if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
//{ fprintf(in2,"fi=%d...\r\n",fi);
// fclose(in2);
// }
}
fclose(in0);
// task 2:刷新显示程序 127.0.0.1 :6006端口
CSocket->Active=true;
CSocket->Socket->SendText("UDISK_REFRESH");
CSocket->Active=false;
// 启动后台复制线程
rundll=true;
}
else
{ DISocket->Socket->SendText("提示:找不到U盘的播放配置文件,请使用计算机MyTV软件生成播放文件!");
//if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
//{ fprintf(in2,"open file fall!\r\n");
// fclose(in2);
// }
}
}
catch(...)
{ //if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
//{ fprintf(in2,"open file fall!2\r\n");
// fclose(in2);
// }
}
}
TForm::WndProc(Message);
if(rundll)
{ cpm=new CopyMoive(true);
cpm->Resume();
//if ((in2 = fopen("c:\\t.txt", "at"))!= NULL)
// { fprintf(in2,"rundll...\r\n");
// fclose(in2);
// }
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CSocketError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
ErrorCode=0;
}
//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit1.h"
#include "UVD_IFC.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall CopyMoive::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall CopyMoive::CopyMoive(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall CopyMoive::Execute()
{FILE *in20;
//STEP1 :获取磁盘的剩余空间,获取文件的大小
//STEP2:如果够拷贝则拷贝,
//STEP3:否则删除磁盘中创建时间在一天前、等级最低的文件
//STEP4: GOTO STEP1
if ((in20 = fopen(MainForm->path.c_str(), "rb"))!= NULL)
{ int fi;
int savelevel=0;
FHEAD fhead;
FRED fred;
String delcmd;
String Sql;
// task 1:存入数据库 udisk
fread(&fhead, sizeof(FHEAD), 1, in20);
Sql.sprintf("select * FROM filesn WHERE sn = '%s'",fhead.SN);
MainForm->UpdateQuery->Close();
MainForm->UpdateQuery->SQL->Clear();
MainForm->UpdateQuery->SQL->Add(Sql);
MainForm->UpdateQuery->Open();
if(MainForm->UpdateQuery->RecordCount>0)
{ fclose(in20);
MainForm->UpdateQuery->Close();
return;
}
//写入数据库
Sql.sprintf("INSERT INTO filesn (SN) VALUES ('%s')",fhead.SN);
MainForm->UpdateQuery->Close();
MainForm->UpdateQuery->SQL->Clear();
MainForm->UpdateQuery->SQL->Add(Sql);
MainForm->UpdateQuery->ExecSQL();
//删除临时文件夹
delcmd.sprintf("%s%d\\",LPATH,savelevel);
DelTree(delcmd);
Sql.sprintf("DELETE FROM Ldisk WHERE Save = 0");
MainForm->UpdateQuery->Close();
MainForm->UpdateQuery->SQL->Clear();
MainForm->UpdateQuery->SQL->Add(Sql);
MainForm->UpdateQuery->ExecSQL();
for_fi: for(fi=0;fi<fhead.Num;fi++)
{ fread(&fred, sizeof(FRED), 1, in20);
if(fred.IsCopy)
{ _ULARGE_INTEGER freespace,totalspace,userspace;
HANDLE hFile;
DWORD dwFileSize = 0;
int filesz,disksz;//以兆位单位的
//STEP1 :获取磁盘的剩余空间,获取文件的大小
hFile = CreateFile(fred.Path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE!=hFile)
{ bool NotCopy=false;
dwFileSize = GetFileSize(hFile,NULL)/1024/1024;
CloseHandle(hFile);
filesz=dwFileSize;
int totalsz;
do
{ ::GetDiskFreeSpaceEx(LDISK,&freespace,&totalspace,&userspace);
disksz=userspace.QuadPart/1024/1024;
totalsz=totalspace.QuadPart/1024/1024;
if(filesz>(totalsz-50))
{ String temp;
temp.sprintf("提示:磁盘空间太小无法复制 %s 该文件!",fred.Label);
MainForm->DISocket->Socket->SendText(temp);
goto for_fi;
}
//STEP2:如果够拷贝则拷贝,
if(filesz<(disksz-50))
{
String dFileName=GetFileName(fred.Path,fred.Save);
CopyFile(fred.Path,dFileName.c_str(),true);
NotCopy=true;
//写入数据库
Sql.sprintf("INSERT INTO Ldisk (No,Page,SubNo,Save,Type,Label,Path,Key0,Key1,Key2,Key3,Key4,Key5,Key6,Key7,Key8,Key9,KeyLeft,KeyRight,KeyUp,KeyDown) VALUES (%d,%d,%d,%d,%d,'%s','%s',%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
(fred.NO%10),(fred.NO/10),fred.SubNo,fred.Save,fred.Type,fred.Label,dFileName.c_str(),
fred.key[0],fred.key[1],fred.key[2],fred.key[3],fred.key[4],fred.key[5],fred.key[6],
fred.key[7],fred.key[8],fred.key[9],fred.key[10],fred.key[11],fred.key[12],fred.key[13]);
MainForm->UpdateQuery->Close();
MainForm->UpdateQuery->SQL->Clear();
MainForm->UpdateQuery->SQL->Add(Sql);
MainForm->UpdateQuery->ExecSQL();
}
else//STEP3:否则删除磁盘中创建时间在一天前、等级最低的文件
{ //删除临时文件夹
savelevel++;
if(savelevel>=3)
{String temp;
temp.sprintf("提示:磁盘空间太小无法复制 %s 该文件!",fred.Label);
MainForm->DISocket->Socket->SendText(temp);
goto end_if;
}
else
{ delcmd.sprintf("%s%d\\",LPATH,savelevel);
DelTree(delcmd);
Sql.sprintf("DELETE FROM Ldisk WHERE Save = %d",savelevel);
MainForm->UpdateQuery->Close();
MainForm->UpdateQuery->SQL->Clear();
MainForm->UpdateQuery->SQL->Add(Sql);
MainForm->UpdateQuery->ExecSQL();
}
}
}while(!NotCopy);
}//..if(INVALID_HANDL
}//..if(fred.IsCopy)
}//..for(fi..
end_if: fclose(in20);
}//..if ((in =
}
//---------------------------------------------------------------------------
String __fastcall CopyMoive::GetFileName(String fpath,int SaveLevel)
{ int p1;
Word Year, Month, Day, Hour, Min, Sec, MSec;
String tph=fpath;
String FileName;
do
{ p1=tph.AnsiPos(".");
if(p1>0)
tph=tph.SubString(p1+1,tph.Length());
}while(p1);
TDateTime dtPresent = Now();
DecodeDate(dtPresent, Year, Month, Day);
DecodeTime(dtPresent, Hour, Min, Sec, MSec);
FileName.sprintf("%d\\%d%d%d%d%d%d%d%d.%s",SaveLevel,Year, Month, Day,Hour, Min, Sec, MSec,rand()%10,tph.c_str());
FileName=LPATH+FileName;
return (FileName);
}
//---------------------------------------------------------------------------
void __fastcall CopyMoive::DelTree(String FileDir)
{ TSHFileOpStruct *Dir;
String strTemp;
Dir = (TSHFileOpStruct*)malloc(sizeof(TSHFileOpStruct));
try
{ Dir->hwnd = this;
Dir->wFunc = FO_DELETE;
strTemp=FileDir+"*.*"+'\0';
Dir->pFrom =strTemp.c_str();
Dir->pTo = FileDir.c_str();
Dir->fFlags = FOF_NOCONFIRMMKDIR+FOF_SILENT+FOF_NOCONFIRMATION;
SHFileOperation(Dir);
}
catch(...)
{ if(Dir!=NULL)
free(Dir);
}
if(Dir!=NULL)
free(Dir);
}