My problem is probably best described in this question:
Auto-opening side-loaded taskpane
But, the answer given won't work for me. I work at a company and setting up a new PC is not an option.
I wrote an Office (Word) Add-In (Office API/JS) and I want it to auto-open when a user opens one of the documents listed on my website. When a user selects a document to download, I open the document on the web server before downloading it and add some extra OpenXML parts in the document using OpenXML to make it open the Add-In. Here's the code:
//params:
// wordDoc - the WordProcessing object being updated
//_WebExtensionStoreReferenceId = GUID of Add-In (the <Id> tag in Add-In manifest)
//_WebExtensionStoreReferenceVersion = "1.0.0.1" - matches version in manifest
//_WebExtensionStoreReferenceStore = path to manifest file
//_WebExtensionStoreReferenceStoreType = "FileSystem"
public static void AddWebExTaskpanesPart(WordprocessingDocument wordDoc,
string _WebExtensionStoreReferenceId, string _WebExtensionStoreReferenceVersion, string _WebExtensionStoreReferenceStore, string _WebExtensionStoreReferenceStoreType)
{
wordDoc.DeletePartsRecursivelyOfType<WebExTaskpanesPart>();
wordDoc.DeletePartsRecursivelyOfType<WebExtensionPart>();
WebExTaskpanesPart webExTaskpanesPart = wordDoc.AddWebExTaskpanesPart();
WebExtensionPart webExtensionPart = webExTaskpanesPart.AddNewPart<WebExtensionPart>("rId1");
We.WebExtension webExtension = new We.WebExtension() { Id = _WebExtensionStoreReferenceId };
webExtension.AddNamespaceDeclaration("we", "http://schemas.microsoft.com/office/webextensions/webextension/2010/11");
We.WebExtensionStoreReference webExtensionStoreReference = new We.WebExtensionStoreReference()
{
Id = _WebExtensionStoreReferenceId,
Version = _WebExtensionStoreReferenceVersion,
Store = _WebExtensionStoreReferenceStore,
StoreType = _WebExtensionStoreReferenceStoreType
};
We.WebExtensionReferenceList webExtensionReferenceList = new We.WebExtensionReferenceList();
We.WebExtensionPropertyBag webExtensionPropertyBag = new We.WebExtensionPropertyBag();
We.WebExtensionProperty webExtensionProperty = new We.WebExtensionProperty() { Name = "Office.AutoShowTaskpaneWithDocument", Value = "true" };
webExtensionPropertyBag.Append(webExtensionProperty);
We.WebExtensionBindingList webExtensionBindingList = new We.WebExtensionBindingList();
We.Snapshot snapshot = new We.Snapshot();
snapshot.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
webExtension.Append(webExtensionStoreReference);
webExtension.Append(webExtensionReferenceList);
webExtension.Append(webExtensionPropertyBag);
webExtension.Append(webExtensionBindingList);
webExtension.Append(snapshot);
webExtensionPart.WebExtension = webExtension;
//TaskPane
Wetp.Taskpanes taskpanes = new Wetp.Taskpanes();
taskpanes.AddNamespaceDeclaration("wetp", "http://schemas.microsoft.com/office/webextensions/taskpanes/2010/11");
Wetp.WebExtensionTaskpane webExtensionTaskpane = new Wetp.WebExtensionTaskpane()
{
DockState = "left",
Visibility = true,
Width = 320D,
Row = 0U,
Locked = false
};
Wetp.WebExtensionPartReference webExtensionPartReference = new Wetp.WebExtensionPartReference() { Id = "rId1" };
webExtensionPartReference.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
webExtensionTaskpane.Append(webExtensionPartReference);
taskpanes.Append(webExtensionTaskpane);
webExTaskpanesPart.Taskpanes = taskpanes;
}
I set up a folder to serve up the referenced Add-In and it seems to work fine when I run it in my development environment. When I run the same code in my QA environment (different domain and certain settings of course), it seems to find the Add-In manifest because it brings up the TaskPane in Word, but it shows "We can't find the task pane to open. Contact the add-in developer for assistance." The Add-In itself seems to be working because when I add it to the Ribbon and click on the button, the Add-In comes up fine and even works with a Word doc.
I compared the two Word documents that were downloaded in dev and QA environments and except for the location of the Add-In manifest they are pretty much identical. I used Open XML SDK Productivity Tool for Microsoft Office to do the comparison (awesome tool by the way).
I don't have admin rights on the QA domain so can't run any debug tools there. Anyone have any ideas?
Did you also put the name "Office.AutoShowTaskpaneWithDocument" as the TaskPaneId in the Actions section in the manifest file?
<Action xsi:type="ShowTaskpane">
<TaskpaneId>Office.AutoShowTaskpaneWithDocument</TaskpaneId>
<SourceLocation resid="Contoso.Taskpane.Url" />
</Action>
I know there are similar questions out there, but this one is a little different (I think).
I used the MATLAB Compiler to convert a .m to an Excel add-in. When I run the add-in on my machine, it works just fine. When I send it to a colleague, they get the "ActiveX component can't create object" error. They have added the add-in no problem.
Is there something going on here that's easily fixed?
MATLAB code:
function mess = createAndRouteOrderWithStyle()
c = startbbrg();
[num,text] = exportToM();
s = emsx('//blp/emapisvc_beta');
order.EMSX_ORDER_TYPE = text(1);
order.EMSX_SIDE = text(2);
order.EMSX_TICKER = text(3);
order.EMSX_AMOUNT = int32(num(1));
%order.EMSX_LIMIT_PRICE = num(2);
order.EMSX_BROKER = text(4);
order.EMSX_HAND_INSTRUCTION = text(5);
order.EMSX_TIF = text(6);
events = createOrderAndRoute(s,order);
mess = events.ERROR_MESSAGE;
close(s);
end
Excel VBA code:
Sub GO()
Cells(10,10).Formula = "=createAndRouteOrderWithStyle()"
End Sub
I wanna close a Quote from a Plugin. Everything works fine online, but if my plugin runs offline in Outlook, i will get an error:
Primary Key must be populated for calls to platform on rich client in offline mode
I close the quote like that:
CloseQuoteRequest req = new CloseQuoteRequest();
req.QuoteClose = myQuote;
req.Value = new OptionSetValue(6);
service.Execute(req);
I traced my plugin while offline and my attributes like the ID of my quote are OK.
Does anyone have some ideas?
the solution is to use a late bound quoteclose entity and provide the activityid guid:
var item = service.retrieve("quote",quoteid, new columnset(true);
var quoteclose = new Entity("quoteclose");
quoteclose.Attributes.Add("quoteid", item.ToEntityReference());
quoteclose.Attributes.Add("subject", "Quote Closed");
quoteclose.Attributes.Add("description", "Quote Closed");
quoteclose.Attributes.Add("quotenumber", item.Attributes["quotenumber"]);
quoteclose.Attributes.Add("ownerid", item.Attributes["ownerid"]);
quoteclose.Attributes.Add("revision", 0);
quoteclose.Attributes.Add("activityid", Guid.NewGuid());
quoteclose.Attributes.Add("actualend", DateTime.Now);
// Close the quote
CloseQuoteRequest closeQuoteRequest = new CloseQuoteRequest()
{
QuoteClose = quoteclose,
Status = new OptionSetValue(5)
};
contextBag.Service.Execute(closeQuoteRequest);
I am trying to write a simple Java program that reads from JBossMQ's jms_messages table using JDBC. I am using JBoss 4.0.4.GA.
I can get the as far as getting a SpyMessage, but how can I get the actual message content (which is an Object in the particular case I'm looking at).
I have a result set "rs" from this statement:
SELECT messageid, messageblob FROM jms_messages WHERE DESTINATION LIKE 'TOPIC.MyTopic%' limit 3"
and then I do this (based on JBoss code):
long messageid = rs.getLong(1);
SpyMessage message = null;
byte[] st = rs.getBytes(2);
ByteArrayInputStream baip = new ByteArrayInputStream(st);
ObjectInputStream ois = new ObjectInputStream(baip);
message = SpyMessage.readMessage(ois);
message.header.messageId = messageid;
String jmstype = message.getJMSType();
String jms_message_id = message.getJMSMessageID();
System.out.println("jmstype=" +jmstype);
System.out.println("jms_message_id=" +jms_message_id);
String propertyName;
Enumeration e = message.getPropertyNames();
while (e.hasMoreElements())
{
propertyName = (String)e.nextElement();
System.out.println("property name = " +propertyName);
}
but I get no properties printed and I don't know how to get my actual object from the SpyMessage (actually a SpyObjectMessage). I'd be grateful for any pointers.
I've tried asking this question on the JBoss forum without reply, so I'm hoping for better luck here.
Thanks.
Sorry - the answer was so obvious I'm not really sure what I was thinking when I posted the question - simply:
Object objMessage = ((SpyObjectMessage)message).getObject();
I have a win form that creates a site in IIS7.
One function needs to open the web.config file and make a few updates. (connection string, smtp, impersonation)
However I do not have the virtual path, just the physical path.
Is there any way I can still use WebConfigurationManager?
I need to use it's ability to find section and read/write.
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
You will have to map the physicalPath to a virtualPath. Here is how you would do that.
using System.Web.Configuration; //Reference the System.Web DLL (project needs to be using .Net 4.0 full, not client framework)
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}
Vadim's answer worked great on our dev server, but bombed out on our live server with the following message:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: site
To correct this, I found another overload for WebConfigurationManager.OpenMappedWebConfiguration that takes the IIS website name as the third parameter. The result is as follows:
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", "iis_website_name");
}
Vadim's answer was exactly what I needed, but I came across the same issue as Kieth, and his solution did the trick!
I thought I'd add though, that the IIS Website name can be retrieved by calling:
System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
Also, cjbarth's code included a tidy solution for those testing in environments where the location of wwwroot and Web.config can vary:
System.Web.HttpContext.Current.Server.MapPath("~");
So with these in mind another slight improvement on Vadim's function would read:
public static Configuration GetWebConfig() {
var webConfigFile = new FileInfo("Web.config");
var wwwRootPath = HttpContext.Current.Server.MapPath("~");
var vdm = new VirtualDirectoryMapping(wwwRootPath, true, webConfigFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
var siteName = HostingEnvironment.ApplicationHost.GetSiteName();
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", siteName);
}
I ended up using Powershell.
$file = "D:\Applications\XXX\Private\XXX\XXXX\web.config"
$configurationAssembly = "System.Configuration, Version=4.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
[Void] [Reflection.Assembly]::Load($configurationAssembly)
$filepath = New-Object System.Configuration.ExeConfigurationFileMap
$filepath.ExeConfigFileName = $file
$configuration = [System.Configuration.ConfigurationManager]::OpenMappedExeConfiguration($filepath,0)
$section = $configuration.GetSection("appSettings")
Write-Host "Set the Protection Provider"
if (-not $section.SectionInformation.IsProtected)
{
$section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
$configuration.Save()
}
Building on Vadim's answer, I found what he wrote didn't exactly work for my situation, so I used this instead:
Dim connectionSettings As New ConnectionStringSettings("mySQLite", ConnectionStringHelper.MyConnectionString)
Dim dummyVirtualPath As String = "/MyApp"
Dim virtualDirMap = New VirtualDirectoryMapping(Server.MapPath("~"), True)
Dim webConfigFileMap = New WebConfigurationFileMap()
webConfigFileMap.VirtualDirectories.Add(dummyVirtualPath, virtualDirMap)
Dim mappedConfigFile = WebConfigurationManager.OpenMappedWebConfiguration(webConfigFileMap, dummyVirtualPath)
Dim config As System.Configuration.Configuration = mappedConfigFile WebConfigurationManager.OpenWebConfiguration(Server.MapPath("~") & "/")
Dim csSection As ConnectionStringsSection = config.ConnectionStrings
If csSection.ConnectionStrings("mySQLite") IsNot Nothing AndAlso csSection.ConnectionStrings("mySQLite").ConnectionString <> connectionSettings.ConnectionString Then
csSection.ConnectionStrings("mySQLite").ConnectionString = connectionSettings.ConnectionString
config.Save()
ConfigurationManager.RefreshSection(csSection.SectionInformation.Name)
End If
In case anyone else is trying what I'm trying and finds this, the purpose of my doing this was to get SimpleMembershipProvider, which inherits from ExtendedMembershipProvider, to work with SQLite. To do that, I created the tables manually per this link: SimpleMembershipProvider in MVC4, and then used this command in my Global.asax file's Application_Start routine:
WebSecurity.InitializeDatabaseConnection(ConnectionStringHelper.MyConnectionString, "System.Data.SQLite", "Users", "UserID", "Email", False)
Which it turns out didn't require me to actually re-write my web.config file at all. (There were also a lot of web.config changes I had to do, but that is even more out of the scope of this question.)