I have developed a console program in C# .NET, that uses Excel Interop.
The program works just fine on my development machine and in the windows server 2008, if I run it from command line.
When I try to schedule a task to run it daily, I got this annoying Interop error:
02/11/2011 00:30:05,000 [1] FATAL My.Program [(null)] - Unable to Microsoft Office Excel open file 'E:\excel.xls' by one of several reasons:
• The file name or path does not exist.
• The file is being used by another program.
• The workbook you are trying to save has the same name as the currently opened book.
System.Runtime.InteropServices.COMException (0x800A03EC): Unable to access the Microsoft Office Excel file 'E:\excel.xls' by one of several reasons:
• The file name or path does not exist.
• The file is being used by another program.
• The workbook you are trying to save has the same name as the currently opened book.
in Microsoft.Office.Interop.Excel.Workbooks.Open (String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, IgnoreReadOnlyRecommended Object, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad)
The file 'e:\excel.xls' exists and if completely closed when the program starts, because if I try to run the same program in my command line, it ended as expected.
I also have setup my task to run as Administrator, so it shouldn't be permissions issues.
Can you help me?
Check this out. Looks like you have to create a folder to get this thing to work right.
C:\Windows\System32\config\systemprofile\Desktop
Taken from this article here
http://social.msdn.microsoft.com/Forums/en/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91
In short make sure to create these folders with appropriate rights for the profile used in the task scheduler and that folder is is NOT SET as readonly:
C:\Windows\System32\config\systemprofile\Desktop
C:\Windows\SysWOW64\config\systemprofile\Desktop
And check this if doesn't work:
From the Start menu, click Run and type Dcomcnfg.exe.
In Component Services, click Console root, expand Component Services, expand Computers, expand My computer,expand DCOMConfig.
Search for relevant app, such as Microsoft Word 14.0 Object Library. Click on it.
Right click and select Properties.
On security tab, select Customize in "Launch and Activation" section.
Click edit and add identity of app pool under which you application is running.
Repeat above step for "Access Permission"
Create a directory “Desktop” under:
“C:\windows\system32\config\systemprofile\Desktop”
AND
“C:\windows\SysWow64\config\systemprofile\Desktop” for 64 bit operating systems
Grant full access to this folder for the user running the service.
It should solve your problem.
Things can get a bit weird when you do Office Automation from a scheduled task, so I'd suggest trying a different user account.
If it works when you're logged in, then I'd suggest setting up the task scheduler to run it under your account. If that still works, then create a new account with the same kind of permissions as your account and have it run under that account.
Otherwise, try logging on as the administrator account and make sure that the app runs when logged in as administrator. For example, maybe there is some bit of Office that gets setup during the first interactive login by the user or similar.
The file 'e:\excel.xls' exists
It doesn't. Mapped drive letters like E: are per-user. The drive is valid only under your user account, the scheduled task is probably running using another account. Instead of tinkering with accounts, the best thing to do is to use a universal name. Like \\server\share\excel.xls, that's valid for any account. Ask more questions about it at serverfault.com
I was struggling to get this to work. I had been all over google, I thought that I had solved my problem with help of one thread that had a drop down while setting up the scheduled task that allowed you to select XP as the "Configure for" option, the XP option is only available when creating the task from the beginning. That worked fine as long as the owner of the scheduled task was actually logged into the machine.
I finally was able to correct it in the DCOM config by adjusting the Identity and hard coding a user to the panel.
Related
edI have C# ASP.NET 4.5 Webform application and use the following code:
if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);
EventLog.WriteEntry(sSource, message, level);
Since the first line was failing I created
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\IDDISLOG in registry
I get the following exception on WriteEntry Method:
Cannot open log for source 'IDDISLOG'. You may not have write access.
Searched other similar questions but none worked for me.
Here is what I have done so far:
Added "Network service" to the project file folder
Added Network service to and gave it full access.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
Added Nertwork service to and gave it full access.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security
Checked and saw w3wp.exe *32 process runs with User Name ASP.Net v4.0.
So added ASP.Net v4.0 to
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
Still, error remains
Your user account may not have sufficient privileges to create an event source, which only administrator accounts can do. If you can log in as an administrator, either run your code again or add a folder here: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\IDDISLOG
That should allow your application to write to the event log with that source. You may need to configure the actual registry entry further to suit your needs.
In IIS (Windows server), you should change de identity used by de app pool, so the new identity has permission to write to the event log.
Select the app pool and advanced settings. then edit and insert a custom account, althoug local system will suffice. If you use a custom account be sure not to use a user whose password is going to expire, because when it happens logging to event log will fail.
Does someone get any hint for accessing Microsoft.Web.Administration.ServerManager.Sites collection on Win8.1 (and Win8) if the user got no right on file "%SystemRoot%\System32\inetsrv\config\redirection.config" ?
Because the user will get UnauthorizedAccessException in this case...
More largely, on Win8 you can get into trouble on any Microsoft.Web.Administration.ServerManager property if your user has no right on "%SystemRoot%\System32\inetsrv\config".
This works perfectly on Win7, W2008 and W2012..
HowTo: http://www.iis.net/learn/manage/scripting/how-to-use-microsoftwebadministration
I need this in a WiX c# Custom Action launched in 'client' step (while in UI) to browse installed Web sites and applications on them for unicity check on new WebApplication name.
Of course, I cant find any relevant answer for this while googling. There are only a few answers out and they hint to launch with elevated privilege or change the rights on the folder, witch of course is not feasible in a regular user setup UI process.
Ex: http://sharepointyankee.com/2011/03/30/system-unauthorizedaccessexception-filename-redirection-config/
Just for information, it seems to be no way to get rid of this...
So I choose to modify my Custom Action to ignore this case by catching UnauthorizedAccessException and still set success for unicity check and return a success for the CA call.
In this case in client step I won't get a failure, with counterpart that I can't get the real result of the unicity check. But I get the result if it wont fail with UnauthorizedAccessException and I can spawn a dialog to the user inviting him to change the site name.
Then in server step where by the way this check ever works I do the same test to be able to fail the setup with a clear message if the website is not unique.
This is not the best for the user who must then restart the setup to change the site name but it works and avoid strange failures by trying to create two websites with the same name.
I have a problem with starting the Excel Application under a particular user.
I try to schedule this script (C#) through an application X (not Windows Task Scheduler. And this application will always use a service account to run services on the server). If I run the C# script in command prompt under the same user, it runs. Under the application X, which uses the exact same user, to initiate the C# script, it fails to open the Excel application (not sufficient permission?).
This script calls:
app.Workbooks.Open(ExcelFileName,0,false,Type.missing....), yet it gives the following error:
Microsoft Excel cannot access the file "...". There are several possible reasons:
-The file name or path does not exist.
-The file is being used by another program.
-The workbook you are trying to save has the same name as a currently open workbook.
I tried all the methods that I found online to no avail.
Create directory “C:\Windows\SysWOW64\config\systemprofile\Desktop” (for 64 bit Windows) or “C:\Windows\System32\config\systemprofile\Desktop” (for 32 bit Windows). Then Set full control permissions on Desktop directory above (for example in Win7 & IIS 7 & DefaultAppPool set permissions for user “IIS AppPool\DefaultAppPool”)
Changed the DCOM config for the Microsoft Excel application to include this user for Local/Remote Launch and Access
Enabled all macros in Excel and set the Trust Center.
Add the user to have full control on all folders that contain the Excel file.
Under DCOM config, Microsoft Excel Application, if I modify the Identity tab to check on "This User" and enter the username/password to let Excel always run under that user. Then the application runs perfectly. However, other users can't run the excel application on their own with the following error: "Cannot use object linking and embedding". If I check "Use the launching user", then Excel can't be launched. No errors in the logs or events anywhere to check.
Yet, still the same error. I think it's permission but I am not sure where and what to do for this to work.
Now, normally, when I run this excel report, I can double-click on the file and it'd automatically run, save the new parameters into the current file and generate a new excel file (with date attached to the file name). That means there is a change (save) to the original file.
I appreciate all your help!
I found the problem is the layer of security in the server!
Creating the Desktop folder inside the C:\Windows\System32\config\systemprofile and giving the service account permission to access the desktop folder is not enough.
I modified the C:\Windows\System32\config (or C:\windows\SysWOW64\config) folder to allow permission to the service account in security tab.
Then I also had to set up the same permission for the sub folder C:\Windows\System32\config\systemprofile (or C:\windows\SysWOW64\config\systemprofile) for the service account.
This works!
Microsoft Excel cannot access the file in Server 2012 Excel 2016.. checked various solutions online to create folder desktop in C:\Windows\SysWOW64\config\systemprofile\desktop.. didn't work for this but then i added a folder desktop in System32 and that definitely worked.
Since I have 64-bit Excel installed, the proper directory turned out to be the
c:\windows\system32\config\systemprofile\desktop
I ran across another way you can get this error: when you try to save a file with an "illegal" name, such as one with whacks (forward slashes) in it.
For that reason, it would seem reasonable that the err msg would give that as one possible explanation of the problem, but...no!
Specifically, I was trying to save a file named C:\RoboReporter\ABUELITOS\20160524_1327\ABUELITOS - Fill Rate - 4\1\61910B10
The whacks (shown as backwhacks in the copied exception text, but seen as forwardwhacks when hovering over the value when debugging) were the cause of the discombobulation. Once I fixed that by replacing whacks with underscores:
filename = String.Format("{0}\\{1} - Fill Rate - {2}.xlsx", uniqueFolder, _unit, _begDate.ToShortDateString());
filename = filename.Replace("/", "_");
...all went swimmingly.
I have a C# application, and I need to dump some output to a log file during operation. I am wanting to give the user the option of where to locate the log file, but by the client request it needs to default to the current application location, which is normally /Program Files/.
When I deploy my application on a Win7/Vista machine, though, the application does not write the log file unless I run the program as an Administrator. At the same time, it seems to be silently handling the case where it cannot write the file, as I am currently handling all exceptions being thrown during the file creation and writing process.
I am currently trying to detect lack of write permission by both:
A) Creating a DirectorySecurity object by calling "Directory.GetAccessControl()" and
B) Checking security priviledges with the "SecurityManager.IsGranted(permissions)" method,
but A does not throw an exception when I expect it to, and B returns true every time.
I have seen numerous posts related to this topic, but they all give the solution of just writing to Application.UserAppDataFolder or some variation of it. My client has specifically asked to default to the current Application path, so I need to at least find a way to gracefully warn them when writing the log file is going to silently fail.
Note: My current code works find on Windows XP (since there are no UAC, I assume). Basically all I need to know is why all my calls are telling me that writing the file is going fine, when the file is never created at all unless I am running as Admin.
Thanks!
Windows Vista and 7 will write files to the Program Files directory just fine.
Well, not really, but the program thinks it's just fine. In reality, the file is written to the current user's VirtualStore directory; that is, in %userprofile%\AppData\Local\VirtualStore\Program Files
You can include a manifest file to disable this behavior for your application to get the results you expect.
You can force the os to run your app as Admin.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
There are three ways your app can run - elevated, deliberately not elevated (manifest saying asInvoker), or accidentally not elevated (no manifest). Elevated apps will be able to write to Program Files. Deliberately not elevated apps will get access denied. Accidentally not elevated apps will succeed but the file will be written elsewhere. This last case is what's happening to you. It didn't silently fail. You just don't know where the files are. See http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx for screenshots.
Therefore if the users insist on the current directory, you should add a manifest requesting asInvoker. You will then get AccessDenied and they will see the error message. I think they are odd for wanting this. Ask them if they are ok with one extra click to find them: if so, keep your app using virtualization (I really disapprove) by having no manifest and then train them to click the Compatibility Files button.
My preference: write elsewhere and manifest to asInvoker. My second choice: stick with current directory, no manifest, train them to find virtualized files. My third choice: stick with current directory, manifest to asInvoker, users see error messages when log files are not written, but logs are lost.
I am experiencing the same problem. I have an xml file that i am writing to...When I install the app(C sharp) and try to run the application am getting an exception due to write permission. When I change the file permission (give read permission to users) it is working ok..
The ultimate test for whether you have the rights to write a file is to open it for writing.
I.e.
try
{
File.Open(path, FileMode.OpenOrCreate);
...
}
catch(SecurityException)
{
... it failed for security reasons
}
catch(Exception)
{
... it failed for other reasons
}
Besides Stefan P.'s suggestion to elevate the app to run as admin, you could also modify the installation folder permission on install to to add the Users group to have write access. Then the application would work as well.
Moving the log file location would be the best option though.
I have an application that is useable by all users (admin or limited) in .NET (C# specifically).
When the application first launches - it creates a few files that it needs in the C:\Documents and Settings\All Users\Documents\ for all subsequent launches.
If the limited user in XP is the FIRST user to launch the application it creates the files fine and both the limited user and administrators can run fine.
However if the Administrator (or I am guessing a different limited user) is the first to launch the application then the limited user is NOT able to run the application.
The two files that it is NOT able to read/write to if created by an Administrator is a Log4Net log file and a SQLite db file.
The SQLite database file is being created with a straitforward .NET File.Copy(sourcepath, destinationpath). The sourcepath is a seed database file installed with the application - so on first run it copies that from the C:\Program Files\app install\seed.db
Is there a way to set the permissions on the file when I copy it? File.SetAccessControl() perhaps? I am not clear on how that works.
The other issue is that the log4Net rolling file appender will not roll the old file and create a new as the old file was created by the admin user when they ran the app.
Any ideas? Ironically this all works perfectly fine in Vista with limited/admin accounts - this is ONLY happening in XP with admin/limited accounts.
I think SetAccessControl is the way to go. Maybe something like this:
// get the existing access controls
FileSecurity fs = File.GetAccessControl(yourFilename);
// add the new rule to the existing settings
fs.AddAccessRule(new FileSystemAccessRule(
#"DOMAIN\Users", // or "BUILTIN\Users", "COMPUTER\AccountName" etc
FileSystemRights.Modify,
AccessControlType.Allow));
// set the updated access controls
File.SetAccessControl(yourFilename, fs);
Note: It's important that you get the existing access control list from the file and then add your new rule to that. If you just create a new access control list from scratch then it will overwrite the existing permissions completely.
Yeah, it's the SetAccessControl method all right, there is a good example here
(the post from satankidneypie)
Good luck