Windows Develop Bookmark and Share   
 index > ClickOnce and Setup & Deployment Projects > HOW TO dynamically download pluggable assemblies in a click-once WPF standalone app?
 

HOW TO dynamically download pluggable assemblies in a click-once WPF standalone app?

I have an extensible WPF app which is module-based (i.e. the app is a shell and doesn't know all the different pieces that will be used in it - it only knows the common interface). Please NOTE: this is not formally using any composite framework or anything. It is simply a shell WPF application with certain pre-defined views. These predefined views need to be dynamically loaded based on pluggable modules installed on our server. By calling a WCF service I'll get back a list of pluggable components the WPF app can use. The WPF Click-Once is stand-alone, but it does implicitly not know what these pluggable component assemblies are. As a result, the click-once manifest will only have the core WPF app dependencies - none of the pluggable extension assemblies.

So, my question is: Is there something in the click-once technology to support this; and, if so, how? Or, is there a way to simply download any of these required assemblies via WCF and "delay" install/load them programmactically?

Thanks and please let me know if you need more information,
Bob

bob.deremer  Thursday, September 17, 2009 10:35 AM

Hi Bob,

Thank you for clarifying the question.

>REQUIREMENT: I need a way to programmatically download assemblies for the "pluggable" components [on demand].

Yes, you can use WCF to download files from server. Here is a good sample talking about this.

http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspx

It declares an IFileTransferService interface and a DownloadFile method. The DownloadRequest class holds the file name. You can look into the sample code and find the following method.

public long DownloadFile(ref string FileName, out System.IO.Stream FileByteStream)

{

Client.FileTransferClient.DownloadRequest inValue = new Client.FileTransferClient.DownloadRequest();

inValue.FileName = FileName;

Client.FileTransferClient.RemoteFileInfo retVal = ((Client.FileTransferClient.IFileTransferService)(this)).DownloadFile(inValue);

FileName = retVal.FileName;

FileByteStream = retVal.FileByteStream;

return retVal.Length;

}

Once you want to download a file, you can call DownloadFile method and pass FileName, FileByteStream. If you want to know more about WCF technology, you can post the question on the WCF forums. The experts on that forum are more professional on WCF technology.

>QUESTION: What is the recommended way to do this in a client WPF app? Can ClickOnce do this, or is it better to do this assembly loading myself?

As Robin and I have said ClickOnce doesn’t support that function. However you can still publish your main app with ClickOnce. That app only contains necessary assemblies to start your first form. After that form being shown, you can download components via WCF based on the user’s choice.

Hope I have not misunderstood you this time. If you have anything unclear, please feel free to tell me.

Sincerely,

Kira Qian

Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
  • Marked As Answer bybob.deremer Monday, September 21, 2009 1:55 PM
  •  
Kira Qian  Monday, September 21, 2009 5:25 AM

Hi Bob,

Based on my understanding, the WPF application you have developed doesn’t have determinate function. It depends on the assembly to be loaded. Once you replace the assembly (DLL) with another one who has the same name as the current one but with different implementation code, your application will performance different task. Is it right?

If my understanding is correct. I think ClickOnce cannot meet this kind of requirement. If your user installed a version, the application will detect update from the update URL. Only when you publish a new version, the user will receive update prompt. All the assemblies on the publish site will be downloaded and install onto the user’s computer.

ClickOnce deployment will deploy a whole application to the publish site (CD-Rom, Net share, IIS etc.), It doesn’t support to deploy part of the application. Also it doesn’t support to dynamically download assembly.

My suggestion is you can upload these assemblies to a net share. In your application, you can put the assemblies�location information into your configuration files. Then dynamically load these assemblies in your application.

If I misunderstood your meaning, please feel free to tell me.

More information about ClickOnce

http://msdn.microsoft.com/en-us/library/142dbbz4%28VS.80%29.aspx

Sincerely,

Kira Qian

Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Friday, September 18, 2009 8:46 AM

Hi Kira,

No, your understanding is not quite right. The name has nothing to do with how this will work. Here is a brief description of what the WPF app must do when started:

1) [on the client machine] the WPF app will start up and display 2 columns. the left column is a type of "palette" the user can select pluggable components from. The things in this palette are loaded froma service call that reads the information from the data base. You canthink of this like the Activity list in the WF designer - where new Activities just "show up" when put in the proper location. Only, in my case, the new "components" are determined by a service call, where I must download the assemblies.
2) this content on the left is also extensible - anyone who implements the proper interface/aspect(s) can install a new component into our system and the WPF will automatically make this available when it updates.

REQUIREMENT:I need a way to programmatically download assemblies for the "pluggable" components [on demand].

QUESTION: What is the recommended way to do this in a client WPF app? Can ClickOnce do this, or is it better to do this assembly loading myself?

Thanks,
Bob

bob.deremer  Friday, September 18, 2009 3:13 PM
The short answer is no, ClickOnce won't do this. You have to have a way to deploy the dll's separately.

You can check out MEF which is new, and is basicallya methodology for deploying plug-ins.
http://mef.codeplex.com/

Another idea is to use ClickOnce to deploy the add-ins.

Deploy each of the addins with ClickOnce. Basically, create a Windows Forms application that has the dll(s) as an included file. It should install, then copy the dll to a common location (more on that in a minute) and then exit. You can even set the form's visible property to false so it never shows.

Your menu on the left side can basically be tied to the URL for installing the add-in via ClickOnce. So the guy clicks on it, and it does a process.start on the URL which "installs" the dll, and then you can load it.

As for the common location, the best place for it is in LocalApplicationData. Just create a folder there and copy your files over to it.

string userFilePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 
string myFolder = Path.Combine(userFilePath, "MyCompany");
if (!Directory.Exists(myFolder))
     Directory.CreateDirectory(myFolder);<br/>
You can send down a list of deployment url's and description using a web service.
Anybody else who wants to deploy an add-in for your project can just create a ClickOnce app like this one that copies the files to the common folder, and your app would hopefully be smart enough to pick it up from there somehow.

Just an idea. Other than that, you pretty much have to roll your own downloads and so on for the add-ins.

RobinDotNet
Click here to visit my ClickOnce blog!
RobinDotNet  Friday, September 18, 2009 4:35 PM

Hi Bob,

Thank you for clarifying the question.

>REQUIREMENT: I need a way to programmatically download assemblies for the "pluggable" components [on demand].

Yes, you can use WCF to download files from server. Here is a good sample talking about this.

http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspx

It declares an IFileTransferService interface and a DownloadFile method. The DownloadRequest class holds the file name. You can look into the sample code and find the following method.

public long DownloadFile(ref string FileName, out System.IO.Stream FileByteStream)

{

Client.FileTransferClient.DownloadRequest inValue = new Client.FileTransferClient.DownloadRequest();

inValue.FileName = FileName;

Client.FileTransferClient.RemoteFileInfo retVal = ((Client.FileTransferClient.IFileTransferService)(this)).DownloadFile(inValue);

FileName = retVal.FileName;

FileByteStream = retVal.FileByteStream;

return retVal.Length;

}

Once you want to download a file, you can call DownloadFile method and pass FileName, FileByteStream. If you want to know more about WCF technology, you can post the question on the WCF forums. The experts on that forum are more professional on WCF technology.

>QUESTION: What is the recommended way to do this in a client WPF app? Can ClickOnce do this, or is it better to do this assembly loading myself?

As Robin and I have said ClickOnce doesn’t support that function. However you can still publish your main app with ClickOnce. That app only contains necessary assemblies to start your first form. After that form being shown, you can download components via WCF based on the user’s choice.

Hope I have not misunderstood you this time. If you have anything unclear, please feel free to tell me.

Sincerely,

Kira Qian

Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
  • Marked As Answer bybob.deremer Monday, September 21, 2009 1:55 PM
  •  
Kira Qian  Monday, September 21, 2009 5:25 AM
Thank you Kira and Robin! I think rolling my own using WCF is actually the simplest approach - once I have the plumbing created. This will make it the easiest for anyone creating plug-ins - they can just be posted/copied into the proper place on the server - no clickonce or other requirements.

Regards,
Bob
bob.deremer  Monday, September 21, 2009 1:57 PM

You can use google to search for other answers

Custom Search

More Threads

• Click once installation package FOR IIS -- is this possible?
• Pre-Install process for deployment
• Limited user and automatic updating app
• Isolated property "not imported" failure
• Acquiring Deployment Info from VB
• deploy updates to 100s of clients
• Deployment Project (Setup): Problem with Registry Entry
• ClickOnce deployment with side-by-side com components
• Where is sqlexpr32.exe?
• Problem with Properties and shortcuts