Why does my code fail to create a directory in “C:\Program Files” under Windows 7?

南楼画角 提交于 2020-01-16 18:15:28

问题


I am using Windows 7 and I have to run one program in that windows but that program working in Windows XP. This is a Visual C++ program and I am using Visual Studio 2008 for this. When I am running my application, it does not throw any errors, but it does not create a directory in "c:\program files\". So can anyone help me to create directory and exe file?

This is the code I am using:

char szAppPath[MAX_PATH];
char szFileName[MAX_PATH];
DWORD dwResult;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;

dwResult = ExpandEnvironmentStrings( NULL, szAppPath, MAX_PATH);  // "%ProgramFiles%"


// do same for NSim directory
strcat(szAppPath,"\\NSim");
hFind = FindFirstFile(szAppPath, &FindFileData);

if (hFind == INVALID_HANDLE_VALUE) 
{
    //Directory Does't Exists create New
    if(!CreateDirectory(szAppPath,NULL))  //Throw Error
    {
        MessageBox("Unable to Create N-SIM directory","NSim Installer");
        return ;
    }
} 
else  
{
    //check if is directory or not
    if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
    {
        MessageBox("Can't Create N-SIM directory\n Another file with same name exists","NSim Installer");
        return ;
    }

    FindClose(hFind);
}

//***************************************N-SIM Application****************************
strcpy(szFileName, szAppPath);
HRSRC hRes;

if( bRegister == FALSE)
{
    strcat(szFileName,"\\NSim.exe"); //make same name of the Client & Server in program file
    hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_LANSIMSERVER),RT_RCDATA);

    if(flagUpgrade ==0)
    {
        CString trial = installationDate();   //----- Detemine Expiry Date -----

        setRegistry(trial);
    }
}

回答1:



[edit] I edited the code in the question for readability and removed the commented out code (to see the wood for the trees). It is now obvious that nothing initialises szAppPath before calling strcat(), and calling ExpandEnvironmentStrings with NULL as the first argument is undefined (and certainly useless). Calling strcat() on an unitialised string is not likely to have the desired result. This may be an artefact of not posting the real code, or even of other peoples edits (including mine).


CreateDirectory sets the system error code on error; if you want to know what went wrong, check it! Any answer you get here will be an educated guess.

if(!CreateDirectory(szAppPath,NULL))  //Throw Error
{
    DWORD errorcode = GetLastError(); 
    LPVOID lpMsgBuf;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL, errorcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL );

    MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK); 
    return ;
}

If you just want to get the error code and look it up manually, then a complete directory of codes is available on MSDN, here, I would guess that ERROR_ACCESS_DENIED (5) is most probable. A more elaborate example of error code display is given here.




回答2:


It's a file permissions issue, plain and simple. Programs can't just go rooting around system directories in Windows 7. That's why it works "properly" in Windows XP, but not in newer versions.

I can't tell for sure, but it looks like you're trying to write an installer. If so, why are you reinventing the wheel? There are tons of great setup utilities available—Visual Studio provides a setup project that you can customize to your needs, or look into Inno Setup, my personal favorite. A Google search will turn up plenty of other options that have already solved this problem for you, and innumerable others.

If this isn't an installer, and you're just trying to store application and/or user data in the Program Files folder, I highly recommend that you look elsewhere. You weren't supposed to shove data into the app folder under earlier versions of Windows, and Windows 7 just cuts you off at the knees if you do this. Your best bet is to follow the recommendations that existed from the beginning: Investigate the user and common Application Data folders carefully. Use the SHGetKnownFolderPath function to retrieve the full path to a known folder using its KNOWNFOLDERID. A couple of suggestions:

  • FOLDERID_ProgramData (a shared program data directory for all users)
  • FOLDERID_LocalAppData (a per-user program data directory, non-roaming)
  • FOLDERID_RoamingAppData (a per-user program data directory, roaming)

Alternatively, you can try running the application as an Administrator. You might want to look into creating a manifest that indicates the application requires administrator-level permissions to execute.




回答3:


windows7? Ok, the problem is not with your program. Its with the file system permissions in Windows 7. User programs cannot create files there.




回答4:


I think the problem is lack of privileges. You can debug your project to see whether the CreateDirectory function sets an error as ERROR_ACCESS_DENIED, if it does, you should make your program run with an administrator privilege. Add manifest in your project to do so.




回答5:


It is intended to protect your computer against attack. Well maybe. Or Microsoft deciding to tell you what you are and not allowed to do on your own computer.

In any case you can change your UAC settings if you really have to write there in that way although that obviously exposes you to risk.

Otherwise play nice and do things the Microsoft way, using a proper installer.



来源:https://stackoverflow.com/questions/4583200/why-does-my-code-fail-to-create-a-directory-in-c-program-files-under-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!