LibVLCSharp How To Determine Which DLLs Are Required By An Application? - c#

I am using LibVLCSharp to play an RTSP stream in my Winforms application. The library is great and everything is working fine. However, my ram usage of the application jumped from around 20-30MB to around 140MB! In addition, I have to include about 140MB worth of DLL files with my application, despite the executable being 2MB! The library right now is bascailly the whold VLC media player application bundled with my app.
I only use very limited capabilites of the library (only streaming from an RTSP URL and displaying it in a form, without even and playback capabilities), so I figured there must be a way to include the required DLLs for my app with the program.
Testing my theroy, I tried to randomly remove some DLLs from the libVLC directory. By some guessing and trial and error, I was actually able to remove ~20MB from the library and the stream worked just fine. For example, by removing the DLLs under audio directory, the stream worked well but had no audio (which I don't need in my case). Unfortunately, there is still about ~120MB of DLLs.
I tried searching how to only include the DLLs required by the used features, or how to determine such DLLs such that the rest can be deleted, but I couldn't find any solution.
A similar unanswered question here on stackoverflow: Libvlc - minimal files (functions) set for streaming out

There is no such guidelines because it really depends on what you are trying to do with your app. For example, libavcodec is needed in 99% of the builds, but whether you need the D3D9 plugin depends on the machines on which you will install the app.
Once you have determined what to exclude, you may use exclusion lists in your csproj, like this :
<ItemGroup>
<!-- You can exclude plugin-by-plugin: -->
<VlcWindowsX64ExcludeFiles Include="plugins\gui\libqt_plugin.dll" />
<!-- You can exclude a whole folder. Notice how the wildcard is mandatory when doing exclude on folders -->
<VlcWindowsX64ExcludeFiles Include="plugins\lua\%2A" />
<!-- You can exclude with wildcards -->
<VlcWindowsX64ExcludeFiles Include="plugins\%2A\%2Adummy%2A" />
<!-- You can exclude the same files for Windows x86 -->
<VlcWindowsX86ExcludeFiles Include="#(VlcWindowsX64ExcludeFiles)" />
</ItemGroup>
If you want to only include the plugins you selected, you can do it that way instead :
<ItemGroup>
<!-- Includes the codec folder. Notice how the wildcard is mandatory when doing include on folders -->
<VlcWindowsX64IncludeFiles Include="plugins\codec\%2A" />
<!-- You can include plugin-by-plugin -->
<VlcWindowsX64IncludeFiles Include="plugins\audio_output\libdirectsound_plugin.dll" />
<!-- You can include with wildcards all in d3d9/d3d11 -->
<VlcWindowsX64IncludeFiles Include="plugins\d3d%2A\%2A" />
<!-- You can still exclude things from what you have included -->
<VlcWindowsX64IncludeFiles Include="plugins\codec\libddummy_plugin.dll" />
<!-- You can include the same files for Windows x86 -->
<VlcWindowsX86IncludeFiles Include="#(VlcWindowsX64IncludeFiles)" />
</ItemGroup>
Please see the full documentation here : https://code.videolan.org/videolan/libvlc-nuget/-/blob/master/cherry-picking.md

Related

Including .razor and .xaml (WPF) files in same .csproj

I have a C# project that I would like to include both .razor files and WPF .xaml files inside. This is a plugin project (ClassLibrary) that provides extensions to two apps: a web server hosting razor pages and a WPF desktop application. I would like to avoid having 2 different .csproj projects for this single plugin (and the overall application has numerous plugins so the additional project count would become substantial).
My project is currently targeting net5.0-windows TFM. For WPF support I use <Project Sdk="Microsoft.NET.Sdk" /> and set <UseWPF>true</UseWPF>. This works as expected and my .xaml files are identified as Page files and compile correctly. In order to get the compile to understand the .razor files I change the SDK to <Project Sdk="Microsoft.NET.Sdk.Razor" />. When making this change, however, the compilation of the .xaml/.xaml.cs files fails.
I have attempted to track down the underlying .targets/.props files used in the SDK to see how to support both what is happening using Microsoft.NET.Sdk.Razor and Microsoft.NET.Sdk with UseWPF=true. I'm hoping someone has figured this out already and can help me out or let me know if it is not possible without separating the functionality into multiple projects.

Include Content in csproj with a wildcard

First the problem I'm trying to solve. I work on a large team and we are constantly having merge conflicts on our web.csproj file. The solution I was trying to implement was including content files using a wild card.
I'm trying to include all files in a directory in my web.csproj file like so.
<Content Include="Areas\Public\Client\**\*.js" />
<Content Include="Areas\Public\Client\**\*.html" />
<Content Include="Areas\Public\Client\**\*css" />
This works great at first glance. I can see all files matching these patterns in visual studio. The problem is, if someone deletes a files from Visual Studio, the IDE then enumerates ALL files in the csproj file and removes my wildcard lines above.
Have any of you solved this problem or have any suggestions?
Thanks!
This is not possible in VS 2015 without loosing the functionality to add/rename/move/etc. items and keep the wildcards.
The handling of globbing in project files is only impelmented by the new CPS-based project system in VS 2017, which is not (yet) used for "classic" .NET / ASP.NET projects.
There are ways to add the Content items during the build using globbing patterns (using custom targets) but these will not show up in the solution explorer (which is okay for auto-generated files)

How to Create Multiple App from a single Android app with different contents

I have two programs. First is a desktop app (C#) and the other is an android app.
The C# one makes some text files and puts them in some of android app folders. So we can have multiple android apps with different contents. the android app is pre-compiled. and the c# app just puts the test files in (with 7za) and repackages it (with zipalign).
The problem is, All of these apps have a single source! means same package name and same app name!
And as you know, android considers same package names as same apps!
How can i solve this problem? and create separate apps from a single android app with different text files (contents)
More details:
I have a single android app (test.apk). My C# app should edit this zip file and repackage it. putting text files in assets folder is working good. But by this method, the C# app output's apks all are the same! i can't install them on mobile separately, because android OS replaces them on each other.
I found myself in a similar situation.
I had a single app but built for different customers (having specific customization like resources, properties...). I eventually decided to manage the whole thing using maven.
What I've done is creating a "config" folder in my codebase and inside it I've added pro customer a folder containing the properties, string, pictures related to him.
My structure is something like this:
MyAppBase
src/
build/
BaseAndroidManifest.xml
...
config/
customerA/
logo.png
customerA.xml
customerA.properties
customerB/
customerC/
...
Using maven artifacts for copying, move, replace I've then managed to build customer specific apk in the following way:
1) Create a temporary customer specific source folder where all code is copied to
<copy todir="src_${customer}">
<fileset dir="src"/>
</copy>
2) Rename packages and imports
<!-- Rename main package -->
<move file="src_${customer}/ch/wizche/myapp" tofile="src_${customer}/ch/wizche/${customer}"/>
<!-- Replace package imports with the newly one -->
<replace dir="src_${customer}/" value="ch.wizche.${customer}">
<include name="**/*.java"/>
<replacetoken>ch.wizche.myapp</replacetoken>
</replace>
3) Replace specific resources based on the customer
<!-- Copy images icon to the drawable folder -->
<copy file="./configs/${customer}/ic_launcher_l.png" tofile="./res/drawable-ldpi/ic_launcher.png" overwrite="true" verbose="true"/>
<copy file="./configs/${customer}/ic_launcher_m.png" tofile="./res/drawable-mdpi/ic_launcher.png" overwrite="true" verbose="true"/>
4) Replace "Template" AndroidManifest and injecting customer versions, names, ...
<copy file="./BaseAndroidManifest.xml" tofile="./AndroidManifest.xml" overwrite="true" verbose="true"/>
<replace file="./AndroidManifest.xml" value="ch.wizche.${customer}" token="ch.wizche.myapp"/>
<replace file="./AndroidManifest.xml" value="android:versionCode="${versionCode}" token="android:versionCode="1"/>
5) Signing using customer alias
6) Building APK
7) Deleting temporary customer folder
So, to build a customer specific app, I just need to:
mvn install -Dcustomer=customerA -P release
Hope this may give you some inputs.
I had a similar problem where i wanted multiple apks with different resolutions of graphics in each (a single apk with all images for all display sizes was too big).
I ended up creating a custom build process where i inserted a 'prebuild' AntTask that basically copied over the correct resources for the build and preprocessed the source such that the package was updated for each apk..
can't find any official docs but this should be a good start..using-ant-to-automate-building-android
You might try distributing an unsigned .apk, then sign it using different keys from within the C# app. I've used signapk.jar to sign unsigned .apk's from the command line.
The risk is that you're distributing private keys to your customers. If that's not a concern, since in a sense, they're building their own apps with your tool, then it might be worth a shot.
See the following lines for more info:
How To Sign APK Zip Files
Android App Code Signing without Eclipse on Windows
There is good discussion of this at How to support multiple android version in your code?, which looks at creating multiple versions of an app. The answers contain a clear strategy for doing this, and details of the process involved.

Builds with referenced assemblies on the network

We are starting a new project, and we would like to put some of the assembly references on a networked drive (in the future, these assemblies will be "dropped" by a build server on to the network location).
I had thought that I read somewhere that Visual Studio is smart about network locations, and that when it detects an assembly on a network drive, it would copy the assembly locally and only update it if the assembly changes. I cannot seem to replicate that behavior, though -- every time I build (even a "normal" build, not a rebuild), VS re-downloads the referenced assemblies from the network connection. If your connection happens to be over a VPN, you can really feel it (adds minutes to the build time).
Was I wrong about VS's build behavior, or is there something that I need to do to enable it?
Keep the references local but introduce a pre-build step to copy them down locally using robocopy. Robocopy is part of the OS in Vista onwards and can be installed as part of the resource kit in previous version of windows (like XP).
Here is an msbuild target to invoke robocopy:
<Target Name="SyncReferences">
<Message Text="RemoteReferencesRoot:$(RemoteReferencesRoot)" />
<Message Text="LocalReferencesRoot:$(LocalReferencesRoot)" />
<!-- ensure required properties are set -->
<Error Condition="'$(RemoteReferencesRoot)'==''" Text="RemoteReferencesRoot property not set." />
<Error Condition="'$(LocalReferencesRoot)'==''" Text="LocalReferencesRoot property not set." />
<!-- Robocopy can't handle trailing slash nicely the way we're going to call it -->
<Error Condition="HasTrailingSlash('$(RemoteReferencesRoot)')" Text="RemoteReferencesRoot has a trailing slash. '$(RemoteReferencesRoot)'" />
<Error Condition="HasTrailingSlash('$(LocalReferencesRoot)')" Text="LocalReferencesRoot has a trailing slash. '$(LocalReferencesRoot)'" />
<!-- ensure source and target directories exist -->
<Error Condition="!Exists('$(RemoteReferencesRoot)')" Text="$(RemoteReferencesRoot) does not exist." />
<Error Condition="!Exists('$(LocalReferencesRoot)')" Text="$(LocalReferencesRoot) does not exist." />
<!-- remember to ignore the exit code as robocopy can return values other than 0 -->
<Exec Command='Robocopy /mir /z "$(RemoteReferencesRoot)" "$(LocalReferencesRoot)"' IgnoreExitCode='true'>
<Output PropertyName="RoboCopyExitCode" TaskParameter="ExitCode"/>
</Exec>
<Message Text="RoboCopyExitCode:$(RoboCopyExitCode)" />
<!--Robocopy exit code:-->
<!-- 0 No errors occurred and no files were copied.-->
<!-- 1 One of more files were copied successfully.-->
<!-- 2 Extra files or directories were detected. Examine the log file for more information.-->
<!-- 4 Mismatched files or directories were detected. Examine the log file for more information.-->
<!-- 8 Some files or directories could not be copied and the retry limit was exceeded.-->
<!-- 16 Robocopy did not copy any files. Check the command line parameters and verify that Robocopy has enough rights to write to the destination folder.-->
<Error Condition="$(RoboCopyExitCode)>3" Text="Robocopy returned exit code '$(RoboCopyExitCode)' which indicates a failure." />
</Target>
Here's another option for you. Basically adding a pre-build event that checks to see if the network location assemblies are newer.
What I can recommend is the procedure we use at my company. We have a networked repository of internal assemblies, let's call it \\AssembliesRepository. However, we don't directly reference off of it (what happens if you lose network connectivity?). Instead, each machine has a local folder, let's go with C:\Assemblies, that mirrors \\AssembliesRepository. We use SyncToy to handle mirroring the two locations, and Task Scheduler to run SyncToy at whatever interval we deem appropriate (currently every 15 minutes during the work day). Using this setup, we never need direct access to \\AssembliesRepository, we just drop assemblies in the local folder, and SyncToy handles the rest. Every 15 minutes we have new assemblies, so we build with the latest internal assemblies at all times. Even the build server is setup this way. I can't promise this works for you, but it certainly reduces burden on the network either way.

Using Compass on Windows with Visual Studio C# and ASP.NET

Has anyone done any development of Compass for CSS/SASS in a standard C# ASP.NET environment?
Is there a single distribution I can just download that's ready to go for Windows or do I need install every piece of the equation and build compass myself?
Are there any plugins that make developing with Compass friendlier with VS2008 such as automagical handling of Compass/SASS in builds, syntax highlighting, and/or intellisense support?
If there aren't any VS IDE plugins what are the best options for a standalone text editor for handling coding in Compass?
To complete the last answers, you can install Web Workbench, a plugin for Visual Studio 2010 wich add syntax highlighting, intellisence and some other stuff for the SASS language (SCSS syntax only).
If you prefer using Compass and/or some other tools to compile your CSS, you should disable the built-in compiler. I listed some other SASS compilers here: Using SASS with ASP.NET.
To disable the built-in compiler: select the .scss file in Solution Explorer, go to the Properties window and delete the text from the Custom Tool box.
Since Web Workbench 3 you can now manage more easily what you want to compile with this plugin. See the Mindscape > Web Workbench Settings menu item.
Getting started with Compass,
First yes I have to install Ruby and the compass source and compile up my version of compass I followed the instructions on Compass's Wiki Getting Started.
After getting Compass and all it's dependencies installed and built I created my first project.
compass -f blueprint project-name
Which creates a default project with compass for the blueprint css framework, currently there's a bug in compass with the creation of the grid.png file in the images directory for compass so you need to copy the original grid.png from the source folder
C:\Ruby\lib\ruby\gems\1.8\gems\chriseppstein-compass-0.8.10
\frameworks\blueprint\templates\project
Or similarly located file depending on where you installed everything. One of the most important changes IMO for working with compass on asp.net is to change the SASS CACHE directive of compass. The SASS CACHE creates a bunch of temporary folders in your project directory which probably would have poor outcomes if they ended under source control. So open up config.rb and add this line
sass_options = {:cache_location =>
"#{Compass.configuration.project_path}\\tmp\\sass-cache"}
Make sure to note the escaped backslashs.
After this I modified the names of the folders that compass uses for how I wanted them named inside the config.rb and started getting to it with SASS and Compass. I recommend watching the hour long introduction to compass video it's very helpful and I learned alot from it: Watch the screen cast.
One of the things which this showed me was how to set compass to watch for file system changes and automagic compile the sass to css. By using
compass -w
This is working real well for me, just make sure you keep your css files checked out or turn them off read only if they're under source control if your project doesn't support concurrent checkouts.
For editing I'm using SciTE that's included with Ruby by default for the config.rb files or just the editor window in VS2008. For Sass I came across a big list on the HAML website. jEdit with highlighting syntax file for SASS was what I ended up using after trying a few. I'd still like to find a VS plugin for syntax highlighting so I don't need to use another editor but jEdit is definitely getting the job done.
My answer is a bit antiquated. Before following my original answer, I would recommend exploring the Nuget package SassAndCoffee. The full details can be found here.
How does it work?
SassAndCoffee embeds the original
compilers in the DLL as (Sass 3.2.0
and CoffeeScript 1.1.0 as of this
writing) and uses IronRuby and
Jurassic respectively to execute the
compilers against your source.
Why is
this better than [SOMEOTHERPROJECT]?
No external processes are executed
You don’t have to install Ruby or node.js
It’s in NuGet so you don’t have to fiddle with web.config
Files are cached and are rebuilt as-needed.
I wanted to add another alternative here. If you just want to ensure that compass builds the sass files and includes the css files when you build your ASP.net project you can add the following to your project(csproj) file under the project section:
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release' ">
<Exec Command="compass compile --output-style compressed --force" />
<ItemGroup>
<Content Include="Styles\*.css" />
</ItemGroup>
</Target>
<Target Name="AfterCompile" Condition=" '$(Configuration)' == 'Debug' ">
<Exec Command="compass compile" />
<ItemGroup>
<Content Include="Styles\*.css" />
</ItemGroup>
</Target>
The first Target is for Release and will also compress the css, the other one is for Debug.
If you want to customize paths add a config.rb to the project root folder:
css_dir = "Content"
sass_dir = "Content/Sass"
This all of course requires compass and ruby to be installed and to be in the path of your machine.

Categories

Resources