Word Automation : could not open macro storage - vb.net

My application (vb.net windows application deployed via ClickOnce) uses Word to open and fill .dot templates to create new Word documents. I reference Microsoft Word 14 Object Library and uses this code :
Dim oWord As Word.Application = Nothing
Dim oDoc As Word.Document = Nothing
Try
oWord = New Word.Application
Dim strFileName As String = ""
Select Case strType
Case "LettreReception"
strFileName = Path.Combine(GetParam(1), "Template_LettreReception.dot")
If File.Exists(strFileName) Then
oDoc = oWord.Documents.Add(strFileName)
On the last line I receive "could not open macro storage" error on deployed machines (not on my development machine).
I develop with Windows 7 - Office 2010 - VS 2010 (.Net 3.5). My deployment machine is also a Windows 7 with Office 2010 installed.
I tried to remove normal.dotm (I found some links advicing it) without success. The .dot template used contains no macro.

Check the properties of the word document and make sure the files are unblocked. Sometimes when you get the documents from a different computer or download them from the internet they will be blocked which will cause the the throwing of this exception "could not open macro storage"

Because Word Interop is actually running behind the scenes as if it was running in an interactive session, certain permissions are required of the account used during execution.
Are you using Windows Authentication and impersonation in you web app? If so, the user being impersonated must have local log on rights to the server to run Word... In addition, you must actually log on to the server with that account at least once so that a profile exists on that machine for that user so the registry hive can be loaded. I've also found that you may need to actually run Word at least once as that user (to make sure any first-time initialization messages get taken care of before trying to run Word from code).
If not, then the service account that the application is running under (usually NETWORK SERVICE) requires the aforementioned permissions (which I will describe shortly) and you'll have to do something fancy like loading a registry hive dynamically at run-time. Personally, I prefer implementing an in-code temporary impersonation with a user account that has local log on permissions on the server in question.
Local log on permissions can be a bit tricky depending on your network and group policy configurations (if you want to be somewhat secure and not just use a Domain Admin account).
The reason everything works on your computer running in VS is because the context of the web application is YOUR user account - which, of course, has local log on permissions on your machine with a registry hive that can be loaded.
Now for the permissions:
First, you must run "dcomcnfg" on the server and make the following configuration change:
Right click on Component Services\computers\My Computer\DCOM Config\Microsoft Word 97 - 2003 Document and go to Properties
In the Properties screen, go to the Security tab and change the "Launch and Activation Permissions" to Customize.
Click the Edit button and add the local computer NETWORK SERVICE account (If not using impersonation... If using impersonation, add the appropriate user or group) to the list of users and check "Local Launch" and "Local Activation"
Make sure that the local computer NETWORK SERVICE account (If not using impersonation... If using impersonation, then the appropriate user or group) has appropriate read/modify permissions on the folder(s)and file(s) that you will be opening and/or saving to.
Create a "Desktop" directory under: C:\Windows\System32\config\systemprofile\ and give Full permissions to the local NETWORK SERVICE account (or the account that your ASP .NET application is running under) [NOTE: I believe this and the next step only apply if NOT using impersonation]
Give Modify/Read/Execute permissions on the C:\Windows\System32\config\systemprofile folder
Hope that helps some and wasn't too confusing...

Right click on the file that is opened -> Click the Unblock tick box -> Apply
Worked for me at least.

"could not open macro storage" is telling you that VBA is looking for a particular structured storage file such as a .DOT or .DOC, and looking for the storage (a kind of stream within the file) in that file that contains the VBA code. If it can't open it, possible reasons include:
the container (the .doc/.dot) isn't there
the container cannot be opened with the caller's permissions
the container is there but the storage isn't there (e.g. on the target system there is a container with the expected name, but it contains no macros)
the container is there and the storage is there but cannot be opened with the caller's permissions
So one thing to do is to look through your project looking for anything it references (perhaps even other objects or DLLs that you specified via Tools->References) that is not also being delivered with your template.

Go to the Word document (if it's a template, be sure to open it, not create a new document with it) and disable Protected View:
https://casecomplete.zendesk.com/hc/en-us/articles/200685047-Could-not-open-macro-storage

Related

Prompt for user input during installation

I have developed a vb.net desktop app that connects and interacts with a database. Ideally, I would like to set up the publication project to prompt for user input during installation of the app (when running the *.msi file). Then, this input could be used as constants within the application. This way, the admins can enter the connection info during install rather than managing through config files, etc.
Prompts would include Username, Password, Database name.
Is this possible or is there a better way of implementing this functionality?
Not during install but this is how I accomplish a similar task.
Add a setting to your application called IsUpgrade and set it to true.
Create a settings form to set all of the values you need.
Once the application is installed, have the admin launch it.
Check for IsUpgrade in your starting form load event.
If IsUpgrade then
FormSettings.Show()
'Save settings in FormSettings closing event
My.Settings.IsUpgrade = False
End If

Receiving "The requested operation requires elevation" when trying to create/set outlook object either via early/late binding in Excel-VBA

I am receiving an error which says The requested operation requires elevation when I am trying to create an outlook object either by early binding or late binding method with below statements
Set olApp = New Outlook.Application
or
Set olApp = CreateObject("Outlook.Application")
It only works when I open this Excel file with "Run as Admin" mode and run my macro. Can you help me to resolve this issue? I do not want to run my Excel with "Run as Admin..." mode to execute my code.
I am using MS-Office professional 2013 and I am also part of the administrative group on my machine.
The only reason for this that I can think of, is that you somehow have OUTLOOK.EXE itself configured to run as administrator.
Unless you remove that configuration, the only way to instantiate an Outlook application is through an elevated process, since a non-admin process can't spawn an admin process.
Close all instances of Excel, and possibly reboot your computer.
Or in my case, I was able to use SysInternals Process Explorer to kill all instances of Excel and Access (I use VBA in both, with references between the two).
In Windows 10, I find I cannot do some things in VBA if my Excel or Access are started with normal user rights. I found a search result somewhere (which I now cannot find) that recommended starting them with administrative rights. I did so, and it resolved the error. Since then I created shortcuts to always start them with admin rights.
However, the bookkeeping software we use exports to Excel, and it sometimes creates new instances. So when I look in Process Explorer, I find multiple root-instances of Excel, some with administrator rights and owned by Explorer.exe, and others with user rights and owned by the bookkeeping program or some other Windows automation process.
With Windows Task Manager, it doesn't always show all instances. So without it, if closing Excel doesn't fix the problem, it means there's a hidden instance still running, and the only way to fix it is to reboot (or install Process Explorer and use that).

Able to write file but not read from a network location

I have following network location
Dim myfolder As String = "\\10.0.0.90\myfolder\"
I am able to create a new file in this folder using following code:
File.Create (myfolder)
But when I try to read contents of this folder using code below I get error.
Code
Dim orderedFiles = New System.IO.DirectoryInfo(myfolder).GetFiles()
Error
The system detected a possible attempt to compromise security. Please
ensure that you can contact the server that authenticated you.
File writing is being done by ASP.Net page while reading is done from Windows Service. Could this be the issue?
Windows Service was running as "Local System". I right click on it, went into properties and changed the "Log on as" to some user account and now it can access network folder.

Is it possible to suppress MS Access "Security Warning" prompt without signing the project?

Background: One of my coworkers has a project that is written in VBA to use MS Access 2003 Run-time as a front-end for a MSSQL database. It's an internal project used by multiple users operating in terminal sessions on a Server 2008 R2 box.
Problem: Every time the Access project is opened, users are greeted with a Security Warning:
This file may not be safe if it contains code that was intended to harm your computer.
They have the option to Cancel or Open. The users would like to be able to skip this prompt.
Since the full version of Access is not installed, users cannot alter their individual security levels and the VBA project cannot be signed with selfcert.exe certificates. (I'm not sure that it would work for multiple users anyway?).
Ideal fix: I'm hoping there's GPO or registry key that alters security settings for Access Runtime, but am open to other suggestions. I'm sure the problem could be fixed by purchasing a license for the full version of Access and a certificate from an approved CA, but this project doesn't have any budget for it.
Update: Have confirmed that the guy who put this project together did it in Access 2003 and does not want to re-test for Access 2007/2010 runtimes. So we're stuck with 2003 Runtime.
Very late answer, but it might help someone. There is a way to do this. I created a shell for my Access apps (originally just to auto update my applications), and during this discovered you can completely workaround Access 2003 security (& 2007 etc with Remou's Trusted Locations).
Set the SecurityLevel in the registry, run the mdb via commandline, reset the registry.
Root: HKCU; Subkey: SOFTWARE\Microsoft\Office\11.0\Access\Security; ValueType: dword; ValueName: Level; ValueData: 1; Check: IsAccInstalled('11.0'); Flags: dontcreatekey
Level 1 = Low, No action; 2 = (Default) Medium, Prompt; 3 = High, Deny?
You can also run your mdb with COM, setting the SecurityLevel via COM before opening the mdb.
However COM wont work for runtime (and you cant identify the OS process later via a unique commandline as I needed to)
Answering this one just to say that no, there doesn't appear to be a way to avoid the security warning for Access 2003 Runtime without actually signing the project.

Permissions issues with SQL 2008, Report Builder 2.0

So here's a bit of context for the horror story:
Win 2003 SP2 64bit running on a VM exposed to outside world for web access.
SQL Server 2008 Std SP2 64bit with Reporting Services (RS) installed for native mode (i.e. not sharepoint mode).
IIS 6 .NET 3.5 web site app written to use the web services from RS. The site has been set to use Windows Authentication and nothing else.
To save writting custom authentication since I don't need it for this demo I have set-up a local account in Win 2003, i.e. servername\myDemoUser, effectively allow fake Windows Authentication.
Default.aspx lists folders on RS and the reports from each folder. It also has a link to the Report Builder 2 on the server.
The rsreportserver.config has been changed so that the only <AuthenticationType> is <RSWindowsNTLM> since <RSWindowsNegoiate> can't work since it's across the internet and users will not be on the same network (hence the local account myDemoUser).
The web site app has url of the form: http://mysite.mydomain.co.uk/ and the link on it to the Report Builder is of the form: http://mysite.mydomain.co.uk/services/reportbuilder/reportbuilder_2_0_0_0.application, in this case RS has been configured so the Web services virtual directory is "services".
The web.config for the website app has been set to <identity impersonate="true /> for <locations> for the ASPX pages that access the RS webservice. I even added a <location path="services/reportbuilder"> with the same thing and also to allow anonymous users.
So after all the above I go to the site from a machine that isn't on the network, I get prompted by IE8 for username/password and I enter servername\myDemoUser and the correct password. The homepage is displayed and correctly shows the list of folders and reports from RS. HOWEVER if I click the RS report builder link I get the pop window saying it's doing it's clickonce verfication stuff but after a couple of seconds it shows simple message box saying there was an authentication error. The details button then shows a text file with a bunch of stacktrace stuff in which eventually says that the server returned 401 while accessing the .application file mentioned above.
I turned on failure auditing for logins on the Win 2003 VM and I can see that when the clickonce fails it is trying to use the local machine account I logged into on the external (to my network) machine instead of the credentials I entered into the browser on that machine when testing it.
Much Googling and granting of permissions to Network service, everyone etc... on various folders involved later nothing the Report Builder bit just won't install via clickonce due to permissions or the incorrect use there of.
I'm looking into maybe changing something in the RS to try and grant permissions to the report builder to anonymous but at this point I'm pretty pessimistic that I'll actually find anything. The annoying thing about this is that this a test that doesn't represent the final thing (we'll be using custom authentication in RS) but unfortunately I have to do it, 8(.
Any ideas would be most appreciated.
It turns out that when using fake Windows authentication in this way when the machine you are accessing the site from a machine where you have not logged into the domain then clickOnce won't work because it won't pass the details you enter into the browser as found.
So the solution is to:
1) Log into a (any) domain on the machine that is going to access the clickonce link on your site.
2) In Control Panel go to User Accounts (XP)/Store Users and Passwords (Win 2003), and manage the network passwords for a user (XP) and add in the URL, username and password.
Whenever clickonce fires up for this URL it will pass the username/password specified as opposed to the local machine account.
Either of the above will solve this problem.