Writing to temp directory when app launched via "Open with" - windows

My application (written in Visual C++ 2008) saves a file with extension .xxx (for example). If I right-click on a file with that extension, select "Open with", and then select my application, any programmatic writing to a file inside my application to a temp directory or even to the directory of the file I opened gets redirected automatically (I assume by Windows) to C:\windows\system32. This behavior does not occur when the file is opened inside the application using File > Open or by double-clicking on the file. This redirection to system32 probably started when I switched from Visual C++ 6.0 or with Windows 7, I don't know which. The program has been successfully running for 13 years. I tried to capture in code the current working directory after opening the file via "Open with" by extracting the directory path of the file but it is annoyingly changed to C:\windows\system32. Even the path obtained from GetTempPath is changed to C:\windows\system32. I am assuming Windows security is causing this to happen. Does anyone know anything about this.

Please read carefully the documentation of the GetTempPath function
The path specified by the TMP environment variable.
The path specified by the TEMP environment variable.
The path specified by the USERPROFILE environment variable.
The Windows directory
So there is a change, that the windows directory gets selected as temp path...
Also, please verify that your application has a valid Vista manifest! If this is not existend, then several redirections and virtualisation will happen with your application:
<?xmlversion="1.0" encoding="utf-8" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Or are you talking about the current working directory? The current working directory is mostly "%SYSTEMROOT%\system32 for shell-starting...

Related

Getting Access Denied on reading and writing txt file from Root Folder

I am trying to read .txt file in Maui Program from the location which I am getting from
Path.GetPathRoot(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal));
I am getting access denied error.
What permissions have to give to the windows application.
Reading system root files requires administrator privileges
Run Visual Studio as administrator.
In solution explorer, add new item, select "Application Manifest File".
change
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
to
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

Set permissions for existing folders and files in ProgramData with WiX Toolset

I've inherited a project that uses WIX Toolset (3.10.3) to build the installation package. The application downloads and stores shared data in c:\ProgramData\Vendor\ApplicationName. This path is however not created during the installation, but rather during the execution of the application itself, whenever the path is requested for the first time.
I've now discovered a permissions related problem that occurs when multiple Windows users uses the application. Whenever the application downloads new data files from back-end, it's the current windows user that gets "Full control" permissions for those files. When someone else logs in with another Windows account, they only have read permissions to those files. And these mixed permissions causes problems when the application tries to keep the local files synchronized with back-end.
Since the application doesn't require elevated priviliges, I have to correct this during the installation. As a first step, I've now made sure that the c:\ProgramData\Vendor\ folder is created during installation, and that it gets correct permissions with <util:PermissionEx User="Everyone" GenericAll="yes" />. Since these permissions are inherited, it will solve the problem for all users doing a fresh install.
The problem is that the permissions are only inherited by folders/files created after the installation. This means that users who upgrades from a previous version will still have data files left with mixed permissions. I therefore need to make sure that all existing folders and files gets the new permissions during installation. How do I accomplish this?
Ok, this is how I solved it. Hope it can help someone else in the future.
First, I added the following things to the wxs file for the MSI:
<Directory Id="CommonAppDataFolder">
<Directory Id="ProgramDataVendorFolder" Name="MyVendor">
<!--This will create the \ProgramData\MyVendor\MyProductName\ folder. -->
<Directory Id="ProgramDataAppFolder" Name="MyProductName" />
</Directory>
</Directory>
<DirectoryRef Id="ProgramDataAppFolder">
<Component Id="CmpCreateCommonAppDataFolderWithPermissions" Guid="13ae94b7-9ef5-4181-bfa9-933844a13418" Permanent="yes">
<CreateFolder>
<!--This will ensure that everyone gets full permissions to the folder that we create in the ProgramData folder. -->
<util:PermissionEx User="Everyone" GenericAll="yes" />
</CreateFolder>
</Component>
</DirectoryRef>
And then included it:
<Feature Id="ProductFeature" Title="$(var.ProductName)" Level="1">
<!--Add folder -->
<ComponentRef Id="CmpCreateCommonAppDataFolderWithPermissions" />
</Feature>
These three things made sure that all users had full access to the folder in ProgramData, even if the folder already exists.
But changing the permissions will not be enough, if file virtualisation is already active due to previous permissions problems. To turn off file virtualisation, I added an app.manifest to my executable with:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
Keep in mind that if the previously used VirtualStore contains files that are important, they will not automatically appear in the ProgramData folder.
More info regarding file/registry virtualization can be found here: https://blogs.technet.microsoft.com/mrsnrub/2010/08/11/uac-virtualization-allowing-standard-users-to-update-a-system-protected-area/

How to modify the embedded manifest of an Inno Setup Installer?

I have an Inno Setup installer that worked fine on my machine (Win 7 32-bit), but did not work at all on a test machine (also Win 7 32-bit). After some investigation, I found that the reason is that there is something going wrong when the UAC is set to anything which is not Never notify me. However, if I right click on the installer, and select Run as Administrator, the installer works fine.
I then tried to modify the embedded manifest of the installer (methods described below), so that it will always run as admin, but this is not working as I wished. I have obtained the original manifest using the command
mt.exe -inputresource:installer.exe -out:installer.exe.manifest
I, then, opened the extracted manifest using a text editor and changed the line
<requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
to
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
I then, tried to apply the resulting manifest, by running the command
mt.exe -manifest installer.exe.manifest -updateresource:installer.exe;#1
but the manifest tool gave me the error
mt.exe : manifest authoring error c1010001: Values of attribute "level" not equal in different manifest snippets.
I also tried changing the command to
mt.exe -manifest installer.exe.manifest -outputresource:installer.exe;#1
but this caused the entire installer to be overwritten by nothing more than the resources (i.e. the actual installer was lost).
I also tried opening the installer executable using Visual Studio (Resource Editor), modified the manifest and saved the file, but this gave the same result as the second mt.exe command I used.
Does anybody know what I am doing wrong, or if I am missing out on something ?
You shouldn't modify the manifest of the resulting Inno setup as Inno does any elevation it needs for the PrivilegesRequired directive.
If you do modify the manifest, or manually do "Run as Administrator" then it will break all the ...AsOriginalUser functionality, most importantly, the postinstall flag.
mt.exe and similar resource editors are also very likely to strip the setup data from the setup file as it's appended to the end of the binary.

FileSystemObject - default location

When I debug my application (in the VB6 IDE), I have to specify the absolute path (e.g. c:\logfile.log) to the log file otherwise nothing is written to the log file. However, when the application is live I do not have to specify the absolute path i.e. I can specify logfile.log. Why is this?
The log file is always in the same directory as the .exe and .dll.
Your file is being written to the current working directory.
When your exe is running this is the folder the exe is sat in, however in Debug mode your exe is actually running from the temporary build location (can't actually remember where this is in VB6).
You can test this simply by doing MsgBox(App.Path) in your program and seeing what location appears.
You'll probably find that there is a logfile.log in the location that appears when you run the above command while debugging.

Problem Unblocking Assemblies in Windows 7 Home Premium

I am getting the following error trying to load a basic project template:
Error 12 Could not load the assembly file://\\psf\home\documents\visual studio 2010\Projects\WindowsPhonePivotApplication1\WindowsPhonePivotApplication1\obj\Debug\WindowsPhonePivotApplication1.dll. This assembly may have been downloaded from the Web. If an assembly has been downloaded from the Web, it is flagged by Windows as being a Web file, even if it resides on the local computer. This may prevent it from being used in your project. You can change this designation by changing the file properties. Only unblock assemblies that you trust. See http://go.microsoft.com/fwlink/?LinkId=179545 for more information. WindowsPhonePivotApplication1
I don't have the Security tab when I try and modify the DLL to unblock the assembly. Any advice?
Did you try copying this assembly locally? Currently it seems to be loaded from a network share. You will need to trust that network location if you want to work this way.
Drive:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\caspol.exe -m -ag 1 -url "file:////\computername\sharename*" FullTrust -exclusive on
Check this KB for details... http://support.microsoft.com/kb/320268/
I just ran into this very same problem - trying to compile a Silverlight application inside Parallels Desktop 8 virtual machine on a Mac - where the SL output directory was located on the emulated drive (appears in Windows as a network drive).
Very simple fix. You can open up devenv.exe.config located in C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE and add this line inside the <Runtime> node:
<loadFromRemoteSources enabled="true"/>
e.g.
<?xml version ="1.0"?>
<configuration>
<configSections>
<section name="msbuildToolsets" type="Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>
...
<runtime>
<loadFromRemoteSources enabled="true"/>
...
To edit the devenv.exe.config file you will also need to open NotePad as administrator. After doing the above I can compile my SL application inside Parallels Virtual Machine, but the above also applies to Silverlight applications hosted on a network drive.
I ran into this. These were the steps I took:
Downloaded a file, WP7PiChartsFromDBSOUP.dll, to my downloads folder (everything locally).
Copied this file to c:/Program Files/ referenced it and attempted to build.
Got this error message.
Removed the reference, and followed the steps to unblock.
Referenced and attempted to build: still same error.
Went back to c:/Program files and noted that the file was still blocked. Somehow my attempt to block didn't take. So I tried to unblock, closed the properties dialog, then reopened. Somehow my attempt to unblock didn't appear to be working.
Went to the downloads folder and unblocked the file that was downloaded to this location, tried to unblock, and it seemed to work. So I felt like I was out of the woods. I copied this file over the file in c:/Program Files and reference it in VS2010, closing and reopening VS2010.
Same error message. I rebooted the machine and tried again. Same error message. And I know this is gonna sound crazy, but I renamed the dll from that long name to PieChart.dll.
And it finally worked.
So, either there was a problem with the name, or maybe changing the name somehow caused the change in blocked status to kick in.
I had the same problem trying to build an application on parallels.
I just copied the whole project in a folder under c:/ and works
it seems that parallels shares certain folders (i.e. desktop, documents) between the OS running on the vm and your mac user home folder. because of that windows treats these folders as network shared folder and forbids you to access them.
It's on the General tab in file properties from explorer. Either via the DLL in question, or you can do it on the zip file before you extract if it was a download, there will be an unblock button at the bottom right.
Make sure it's from a trusted source.
I've tried many solutions also with coping file to external usb drive with FAT32 file format, and some other ideas. But finally I've found post by caliban here: Topic about this problem. He links to a program called Streams which helped solving this problem :)
caliban:
Run this line in the command line
streams -s -d directory
download Streams exe
Add to the project a text file named ServiceReferences.ClientConfig having the following contents:
<configuration>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>
Re-build the project.
If you still didn't get your answer, I just found the solution. You are saving the application into the network hardrive. So while creating the application, change the location to something like your local disk e.g.,
C:/Projects
Then you will be able to run it.
I had the same problem over VMWare using a mac to load windows 7, if you see the path it starts like a network path, that's why VS gives out about the security.
Take the entire folder project and put it in a physical path starting with C://program files... , then open and compile, it will work.
Right click on the dll and select properties. You should see a button to unblock the assembly.

Resources