I am creating an installer with InnoSetup. My program requires that I be able to read and write to files as it reads data from my hardware device that is connected over IPv4. I also write to files as I am creating content within my program. I am having issues on a Windows 7 Professional 64bit machine that has a domain account. It is not allowing some .exe files within my program to open as necessary. The .exe files that need to open are reading and writing data from the files to which I have created content with the main exe of my entire program. The error that comes up is when I click a button in one program that will open another .exe file. The error reads Failed to set data for "". It seems as though the argument is being passed for my button link, but the link becomes null where it is trying to open "" file, which does not have a pathway. There appears to be some permission on the file that is rendering its location as unreadable, thus giving the failed to open "" location.
I have setup my installation file with the following flags that I believe should be necessary to allow read/write access in Windows 7.
[setup]
DefaultDirName={localappdata}\{#MyAppName}
; to install to localappdata folder of local user
[Dirs]
Name: "{app}" ; Permissions: users-modify users-full
; to allow the user to have read/write permission of all files within the installation folder. This should not be necessary because localappdata should already have read/write permissions.
This works fine on other machines that have only local user accounts. However, on the same computer that I am having trouble with, I have tried logging in as a local user account and I still find the same errors.
What am I missing to allow the program to read/write to all files within my installation folder, located in c://user/domainaccountaddress/appdata/local/my program directory?
I'm quite new to this, all advice is appreciated.
Related
Dear community members,
We have three of same hardware Windows 7 Professional computers. No one of them is connected to a domain or directory service etc.
We run same executable image on all three computers. In one of them, I had to rename it. Because, with my application's original filename, it has no write access to it's working directory.
I setup full access permisions to USER group in working directory manually but this did not solve.
I suspect some kind of deny mechanism in Windows based on executable's name.
I searched the registry for executable's name but I did not find something relevant or meaningfull.
This situation occured after lot of crashes and updates of my program on that computer (I am a developer). One day, it suddenly started not to open files. I did not touch registry or did not change something other on OS.
My executable's name is karbon_tart.exe
When it start, it calls CreateFile (open mode if exist or create mode if not exist) to open karbon_tart.log file and karbon_tart.ini file.
With the files are exist and without the file exists, I tried two times and none of them, the program can open the files.
But if I just rename the name to karbon_tart_a.exe, program can open files no matter if they are exist or not.
Thank you for your interest
Regards
Ömür Ölmez.
I figured out at the end.
It is because of an old copy of my application in Virtual Store.
I have an add-in in Excel that needs to store some data in the HKEY_LOCAL_MACHINE registry. because of the UAC control in Windows Vista and earlier versions, I added a manifest file. But it is just not working. I even added the manifests in each of the projects of my solution. I have 5 projects in my solution (3 VB projects, 1 c++ and 1 deployment).
I am using VS2005. I added the manifest file to the project (with the requestedExecutionLevel set to "requireAdministrator" and embedded the manifest using mt.exe in a post-build command.
Even with that, I am still getting an access denied to the HKEY_LOCAL_MACHINE. The only thing that is working is when I start Excel as "Run as administrator".
Any clue what the problem might be? Thanks.
Manifests in DLL do not affect the execution level of the application, in this case it's excel.exe.
Here are the options you have:
to run Excel as administrator;
to modify the add-on to write to HKCU rather than HKLM.
If you need to store data available to other users, consider using ProgramData folder (CSIDL_COMMON_APPDATA or FOLDERID_ProgramData). Then your add-on creates a subdirectory inside ProgramData and modifies its permission so that this new directory is writable by anyone (by default, only the user account that created the folder has write permissions, other users can only read).
There are some other options:
You can write a service that your add-on will communicate to write data into HKLM but it's not.
You can create an elevated COM object which will write the data into HKLM.
Although users don't expect Excel to require elevation when run, therefore consider changing your logic so that your add-on does not require elevation at all.
I have full admin privileges on my Windows 7 machine but when I run my application which creates a file on c:\ drive I get error code 5 (Access is denied). I know windows 7 doesn't allow creating files in protected areas like c drive and program files and file explorer brings up 'administrative' message box if I copy a file there from somewhere else after which it does allows but can my application obtain write level access?
In my application, user gets to pick the folder where they want to create the file so if they choose c:\ drive s/he will obviously get this error which is not desirable.
void CTestDlg::OnBnClickedButtonCreate()
{
CFile f;
CFileException e;
TCHAR* pszFileName = _T("c:\\test.txt"); // here i am hard coding path for simplicity.
if(!f.Open(pszFileName, CFile::modeCreate | CFile::modeWrite, &e))
{
TRACE(_T("File could not be opened %d\n"), e.m_cause);
}
}
As far as I have researched it seems I can't by-pass the UAC dialog which is fine but my application don't even present it (which is understandable as well) but what are my options?
I see my only option is to detect this in my own application if this is Windows 7 OS and than check for file path before creating the file and present a more user friendly message 'windows 7 doesn't like you to create file in this folder, choose a different folder or go back to xp'. Is this scheme the way to go on Windows 7? Is there any other way?
As Kolink noted, your application needs to run with administrator privileges. In order to do that automatically, embed a manifest as explained here.
EDIT: For VS2010: Project Properties > Configuration Properties > Linker > Manifest File Change the 'UAC Execution Level' to the desired value.
Either don't try to write to protected areas, or require that your application be run with permissions (right-click => Run as Administrator).
I know I don't like random files appearing in my root - I like my files organised.
If it's the user who provides the path, then you should inform them that the file cannot be saved to this location and ask to provide another name.
Usually the shell, GetSaveFileName function, checks whether the new file can be created in the selected directory before returning, see flag OFN_NOTESTFILECREATE in description of OPENFILENAME structure.
Another option is to handle such situation and to show UAC confirmation yourself. But this solution requires much more effort than it's really worth. You can't elevate the current process, so the operation of saving the file to a protected area has to be implemented in another process. At the same time your current process has the data to be saved, so you'll have to implement the communication between the two processes. Read Designing UAC Applications for Windows Vista for more information.
I have created an installation with inno setup. My app (among other things) after is run creates a pdf file inside a subfolder and then opens it. But windows 7 says access denied and exception pops up. What's wrong? How to grant access to subfolders using innosetup?
Here's the code snippet inside ino:
Source: "C:\Users\Someone\Desktop\NET\Animations\*"; DestDir: "{app}\Animations"; Flags: ignoreversion recursesubdirs createallsubdirs
Presumably because you're trying to copy the file from a different user's private folder. That's off-limits. You can only place files into the current user's folder (the one who is running the install). It's difficult to imagine a good reason why you'd want to do otherwise, anyway.
Try using the {userdocs} constant, instead. Use ExpandConstant to expand it to the full path.
If you need things to go in a location that will be accessible to all users, you need to run the installer with Administrative privileges. Then, you'll be able to read/write from the All Users profile directory.
EDIT: Ah, sorry. I totally missed the part of your question where you said you were trying to do this after installation. I just looked at the code and thought this was something you were having Inno Setup do during the setup process.
It's a completely different answer for something after the installation has completed. Windows 7 (thanks to UAC) doesn't let your app (or any app, for that matter) write to system folders. That includes the Windows directory, as well as the Program Files folder and any of the folders it contains. This is a security measure, intended to stop applications from running amok in places where they don't belong.
You have a couple of different options:
If you absolutely need write access to the Program Files folder, you can prompt the user to elevate your application's process. Basically, that means that you'll be requesting Administrative privileges, and they'll see a box from UAC asking them for a password.
I give more information about how you might go about doing that from a C# application in my answer to this question. You'll follow similar steps for an app written in any other language; you're just calling functions built into the Windows API.
The better option, though, is to modify your application so that it doesn't have to write to system folders. That way, you won't have to run with Administrative privileges. This is the intended model for all standard Windows applications. Microsoft has been recommending it at least since the early days of Windows 2000, but you weren't actually forced into following it until Vista.
I talk more about the various places that an app has write access to (and the various uses of each) in my answer to this question.
My application is not supposed to perform any administrative tasks, so I want a normal User account to be able to run it. Only thing is, my application reads from and writes to a database file; if the user running Windows 7 (Or Vista) installs my app in drive C, the drive's default permission set configuration doesn't allow my app to write data.
How can I allow my app to write to C:, without requiring full administrative privileges?
If the database file exists at install time you can just grant the user write access to the file as part of the installation process (ordinary users do not have this permission by default). If the file needs to be created by the program the user running the program will need modify permissions on the c drive, which is not something that I would recommend.
I'd suggest storing your db file in Documents and Settings / App data / your app / directory. It exists specifically for this purpose. Writing to C:/Program Files is not so good practice. If that's possible in your case, that is.
You need to open UAC (User Account Access) and set security slider to the bottom. Then you can access drive C: as you did in windows XP.
I decided to modify directory permissions in the setup process, so I created an .exe file that changes the permissions of its start-up path, and gives all users access to that path. I simply included that .exe file in my deployment project, and created a Custom Action that would run the file in the Commit phase of installation.
Because the setup asks the user for administrative rights when it is being installed, my .exe also enjoys administrative privileges and can modify the permissions of the installation directory.
In my .exe, I used a Process instance to run the ACL utility shipped with Windows (icacls.exe) as follows:
ICACLS.EXE [TargetDir] /T /C /grant Users:F
(Make sure that [TargetDir] doesn't end with a "\" or the call will fail.)
This gives all users full control access to the target directory.
I could also write .NET code and change directory permissions manually, but I'm a little lazy!
You may however want to inspect your environment conditions thoroughly so that what you do wouldn't become a security hole in your environment; but this was suitable for me.
I hope this helps others who faced the same issue.
The user by default should have write permissions to drive C:, if not, then you will need to change the directory you read from and write to, to the executing directory (C:/Program Files/Your App/) rather than the root of C:
You can get this by
String Path = Path.GetDirectoryName(Application.ExecutablePath);