一个windows端服务拷贝文件到共享文件夹的方法记录

一个需求,需要实现拷贝一个本地文件到共享文件夹的功能,思路是先开启网络共享文件夹的访问,然后执行拷贝命令;


开启网络共享文件夹的免密码访问,需要在cmd.exe命令窗口,使用net use命令,如:

net use \\192.168.21.102 "password" /user:"test"


另外,执行cmd.exe,通常方法是使用system调用或者winexec(两者的区别参考:http://t.csdn.cn/8cDXf),system调用确实可以实现这个功能,但是会出现一个很讨厌的黑色弹框,所以使用CreateProcess的方法;


执行cmd.exe命令不弹出对话框的方法:


static void TcharToChar(const TCHAR* tchar, char* _char)
{
  int iLength;
  //获取字节长度  
  iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);
  //将tchar值赋给_char   
  WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);
} 
//同上 
static void CharToTchar(const char* _char, TCHAR* tchar)
{
  int iLength;
  iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
  MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);
}

static void windows_system(const char* cmd)
{
  PROCESS_INFORMATION p_info;
  STARTUPINFO s_info; 

  memset(&s_info, 0, sizeof(s_info));
  memset(&p_info, 0, sizeof(p_info));
  //隐藏掉可能出现的cmd命令窗口
       //s_info.dwFlags = STARTF_USESHOWWINDOW;
       //s_info.wShowWindow = SW_HIDE;
  SECURITY_ATTRIBUTES sa;
  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;
  _unlink("output.log");

  HANDLE h = CreateFile((L"output.log"),
    FILE_APPEND_DATA,
    FILE_SHARE_WRITE | FILE_SHARE_READ,
    &sa,
    OPEN_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
   
  s_info.cb = sizeof(s_info);
  //s_info.wShowWindow = SW_HIDE;
  s_info.hStdError = h;
  s_info.hStdOutput = h;
  s_info.dwFlags |= STARTF_USESTDHANDLES;
  s_info.hStdInput = NULL;
   
    

  DWORD flags = CREATE_NO_WINDOW;
  TCHAR szCommandLine[255];
  CharToTchar(cmd, szCommandLine);

  if (CreateProcess(NULL, szCommandLine, NULL, NULL, TRUE, flags, NULL, NULL, &s_info, &p_info))
  {
      DWORD dwExitCode;

      WaitForSingleObject(p_info.hProcess, INFINITE);
      GetExitCodeProcess(p_info.hProcess, &dwExitCode);

      CloseHandle(p_info.hProcess);
      CloseHandle(p_info.hThread);
  }
}


拷贝文件到共享文件夹的实现:

DWORD WINAPI UploadThreadFunc(LPVOID p) {
  char* file_path = (char*)p;
  char temp_str[255] = "";
  string record_server_ip = "";

  if (file_path == NULL) {
    return 0;
  }
  string curr_path = GetExePath(); 
  SetCurrentDirectoryA(curr_path.c_str());

  get_record_server_ip(record_server_ip);

#if 0
  string App1 = "upload_file_config_server.bat"; 

  system(App1.c_str());
#else
  /*  注意
        cmd:命令  执行可能需要 "cmd.exe /c ping baidu.com"  需要 /c 才能执行
        cmd.exe /k 执行完命令行不关闭
        cmd.exe /c 执行完命令行马上关闭
  */
  sprintf_s(temp_str, "cmd.exe /c net use \\\\%s \"076104\" \/user:\"test\"", record_server_ip.c_str());

   //system(temp_str);
  //WinExec(temp_str, SW_HIDE);
  windows_system(temp_str);
#endif
  //拷贝文件到服务器
  string cpCmd = "cmd.exe /c COPY /B ";//use windows_system
  //string cpCmd = "COPY /B ";
  string destDir;


  destDir += "\\\\";// 192.168.21.102\\BroadcastServerSharedAudioFile\\record\\";
  destDir += record_server_ip;
  destDir += "\\BroadcastServerSharedAudioFile\\record\\";
  int ret = _access(destDir.c_str(), 0);
  if (ret != 0) {
    ret = mkdir(destDir.c_str());
  }
  time_t time_now = time(0);
  tm* ltm = localtime(&time_now);
  sprintf_s(temp_str, "%d%02d%02d", 1900 + ltm->tm_year, 1 + ltm->tm_mon, ltm->tm_mday);
  destDir += "\\";
  destDir += temp_str;
  ret = _access(destDir.c_str(), 0);
  if (ret != 0) {
    ret = mkdir(destDir.c_str());
  }
   
  cpCmd += file_path;
  cpCmd += " ";
  cpCmd += destDir;
  //cpCmd += "\"";
  //system(cpCmd.c_str());
  windows_system(cpCmd.c_str());
  //WinExec(cpCmd.c_str(), SW_HIDE);


  return 0;
}


参考:CreateProcess函数详解_顺其自然~的博客-CSDN博客_createprocess

CreateProcess 执行 cmd 命令_xmmdbk的博客-CSDN博客_createprocess执行cmd命令



呱牛笔记

请先登录后发表评论
  • 最新评论
  • 总共0条评论