The Scenario
The vendor of GreatLib.dll deploys a custom control. It is getting used in customers Winforms application. GreatLib is strongly named and exposes some types. When these types are used as public properties in the customers forms, they are also available in the Windows Forms designer. Here is, where the hassle starts:
The designer will create items for all those types in the resource file of the form and serialize their default(?) values in those items. Since GreatLib is strongly named, the reference will include the fully qualified name for the assembly. (I think this is what Resgen does?). Such items may look as follows:
<data name="vector3Control1.value" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFRJTE51bWVyaWNzLCBWZXJzaW9uPTQuMi41MzM4LjQ4MDIxLCBD
dWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPThkOWJmNTBlZjg1NDczNGQFAQAAABpJTE51bWVy
aWNzLkRyYXdpbmcuVmVjdG9yMwMAAAADbV94A21feQNtX3oAAAALCwsCAAAAAAAAAAAAAAAAAAAACw==
</value>
</data>
In the Form.Designer.cs file the designer generates some code similar to this in order to read in the resource items:
this.vector3Control1.value = ((ILNumerics.Drawing.Vector3)(resources.GetObject("vector3Control1.value")));
The Problem
Vendor provides an update to GreatLib, the customer replaces the old version with the new version. But the resource file will stay the same! Hence, we either get an InvalidCastExeption on the Designer.cs code or - if the old assembly was not found anymore - a FileNotFoundException.
What is the recommended way to handle strong names in resx files?
Preventing from them completely by using
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
? Or manually transforming the base64 data on each update as suggested by HansPassant?
Related
I am working on an UWP text editor. I have added desktop extension to it to modify system files and other read only files. The problem I have is there is no reliable way to detect if a file has read-only attribute. FileInfo.IsReadOnly doesn't work and StorageFile.Attributes has FileAttributes.ReadOnly when file is dragged and dropped from file explorer.
How do I reliably check whether the file has read only flag or not?
While there is no way to detect the readonly attribute by using dotnet methods, however GetFileAttributesExFromApp can be used to get a lot of attributes(readonly, hidden etc.) of the file that aren't available via StorageFile api. Also, SetFileAttributesFromApp can be used to change/remove these attributes.
Edit
After some research and deep dive in MSDN, I came to know about RetrievePropertiesAsync(IEnumerable<String>) and
SavePropertiesAsync(IEnumerable<KeyValuePair<String,Object>>) methods for Windows.Storage.FileProperties.StorageItemContentProperties which can be used to get and set properties by name (Full list of properties names), the name System.FileAttributes can be used to get file attributes and can be used to detect if read-only flag is present. While retrieving properties always works modifying properties will only work if app has write access to file (Windows.Storage.StorageFile.Attributes doesn't contain ReadOnly flag), although SetFileAttributesFromApp works for that scenario but limitation of SetFileAttributesFromApp is it won't work for sensitive file types (.bat, .cmd etc.). So both those methods could be used combined to have maximum effect.
You can see the Attributes property has ReadOnly or not.
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
foreach (string format in HelperUP.subtitlesFormat)
filePicker.FileTypeFilter.Add(format);
var file = await filePicker.PickSingleFileAsync();
if (file == null)
return;
Debug.WriteLine(file.Attributes);
The reason FileAttributes.ReadOnly throws an exception is that the System.IO APIs don't have access to arbitrary file locations on the hard drive in UWP.
On the other hand, a StorageFile opened in the app via drag & drop has this attribute set too, which is a problem that is continuously being discussed and hopefully will be fixed in a future version.
The only workaround I can think of (apart from always using the desktop extension) is declaring the broadFileSystemAccess capability (I have described the process here for example). This is a capability which gives you access to the whole filesystem and allows you to get a file using an arbitrary path with the StorageFile.GetFileFromPathAsync method (see Docs). Please note you will need to explain why this capability is required when you submit the application to the Microsoft Store.
With broad filesystem access, you could take the drag & drop StorageFile, take its Path and retrieve the same file again using StorageFile.GetFileFromPathAsync. This new copy of the file will no longer have the "false-positive" Read Only attribute and will reflect the actual attribute state from the filesystem.
I have a standard WPF localized application using .resx files. At the moment I have support for en-US (default) en-AU, es, and zh-CN.
Do I need to have a separate resx file for each language, or is there some way to group them? For example, I imagine people with region id en-GB would prefer en-AU over en-US. or zh-TW would definitely prefer zn-CN over en-US. I could certainly just copy the files, but is there an easier way?
You need a seperate resx file for every language and each file has to have the same keys. The matching resx file will be choosen automatically.
You can have one default resx file if that's what you wanted to know, too.
A bit late to this question but I just found it so I might as well give an answer.
I guess there are two options, depending on your needs:
You can define a "Resources.en.resx" that en-GB users will fall back to if there is no specific en-GB resource file defined.
en-GB users will try to look for resources in the following order:
Resources.en-GB.resx
Resources.en.resx
Resources.resx
This works per resource entry. You can define all common "en" resources in Resources.en.resx, and only the differences in Resources.en-AU, so you don't have to copy paste all resources.
You can also manually set the culture depending on the language code: if the user is in en-GB, you could just set the culture to en-AU:
CultureInfo userCulture = CultureInfo.InstalledUICulture;
if(userCulture.Name == "en-AU") // do what you want
I have searched a number of plugins for adding automatic/manual headers/comments/function details in any C/C++ file when open in vim editor, even tried using .vimrc file using autocommands. But they are for while opening a new file. Is there any same for already existing files?
Its very tedious for adding information about a code/function in a large code-base.
lh-cpp provides:
customisable templates for file headers
loaded automatically when a new file is created from the file template, before expanding the dedicated .h/.cpp file template
or on demand as they are 3 ways to trigger a template/snippet expansion (automatically on new files, or on demand with :MuTemplate c/internals/c-file-header here (you can also set an alias to something else) or on snippet expansion). As lh-cpp/mu-template snippets/templates are actually similar to functions/variations points, you can ask to expand only file headers (which are customizable on a per-project basis), or anti-reinclusion guards, and so on.
:DOX command that analyses functions signature to fill the function headers as best as possible
advanced snippets for various kind of classes (entity classes, base classes, copiable classes, exception classes, ...) and should eventually fill as much information as possible in the class doxygen from the class semantics -- I just didn't have enough time yet to implement this feature.
There are at least two approaches, one using abbreviations and one using snippets.
For example, you could use Ultisnips to add a pre established header.
I write Silverlight games using XNA-based Silverlight engines. I have a previous game where I have files (MP3s and text files) with Build Action set to Embedded Resource, and no *.resx file to be seen in my solution.
The game runs fine; you can see the production version here.
On the other hand, my current project doesn't allow this. When I try to make files Embedded Resources, I get a MissingManifestResourceException thrown in my constructor of the main UserControl instance that starts my app. The error message is:
Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "DeenGames.Colosseum.Content.Audio.2.mp3.resources" was correctly embedded or linked into assembly "DeenGames.Colosseum" at compile time, or that all the satellite assemblies required are loadable and fully signed.
I'm very, very, very perplexed. Setting any item's Build Action to Embedded Resource, whether MP3, text, or image, causes this exception.
How the heck do I fix (or debug) this? I'm 99% sure I do not need a .resx file, because my previous projects don't have one.
There's this lovely MSDN page which assures the world that:
In particular, Silverlight embedded resources must always use the
Resource build action, and not the Embedded Resource build action,
which uses a format that Silverlight cannot recognize.
But there's a well-known solution using Assembly.GetExecutingAssembly().GetManifestResourceNames(). In my case, it doesn't show me the resource if it's just a Resource; if it's an Embedded Resource, I can see the file name with dot-delimited namespace (as expected).
Download and see for yourself a very simple working example here. It has two embedded files (.2dg and .map) and compiles/runs without any exceptions OR resx file.
You can also download a broken example here. Replace FlatRedBall.dll with RadiantWrench.dll and watch the working example break. (Use ScreenController.ShowScreen and remove all FRB-referenced code.)
Embedded Resource is a WinForms technology that is depreciated in the Silverlight runtime. Instead, a build action of Resource or Content should be used instead.
When you set an item to Embedded Resource, Silverlight expects this to be a .resx file because this is what happens inside the .csproj or .vbproj file when you create a .resx and add resources to it (the file is marked as Embedded Resource for MSBuild and its resources are simply a None inside of an <ItemGroup/> that are discovered by the ResXGenerator at runtime based off the relative URI folder of "Resources"). If it isn't, it removes it or sets it as Content. You can examine Microsoft.Silverlight.Common.targets (usually in your C:\Program Files (x86)\MSBuild\Microsoft\Silverlight\v4.0 folder) to see how it changes items marked as Embedded Resource - setting to content, setting to none or setting to a .resx file.
If you're looking to just query what resources you have in the project, you could try this somewhat cumbersome approach: Enumerating embedded resources
UPDATE: In looking at your project, this is not really using an Embedded Resource the way WinForms uses this Build Action type or even .resx, per say. It uses a function from the ToolsSilverlight.dll called EmbeddedResourceFileReader.ReadFile. The code for that is:
private static string ReadFile(string fileName, Assembly currentAssembly)
{
string text = EmbeddedResourceHelper.CheckAndSanitizePath(fileName);
string result = "";
using (Stream manifestResourceStream = currentAssembly.GetManifestResourceStream(text))
{
if (manifestResourceStream == null)
{
throw new ArgumentException("Couldn't open " + fileName + ". Make sure the file exists in that directory, and has Build Action set to Embedded Resource.");
}
using (StreamReader streamReader = new StreamReader(manifestResourceStream))
{
result = streamReader.ReadToEnd();
}
}
return result;
}
Your .csproject file lists your files as:
<ItemGroup>
<EmbeddedResource Include="Content\Qadar.2dg" />
<EmbeddedResource Include="Content\Maps\main.map" />
<None Include="Properties\AppManifest.xml" />
</ItemGroup>
All this does is embed, as mentioned with the Microsoft.Silverlight.Common.targets above, your files as common Resources (at a top level, not with the list of other actual resouces) and finds a way to read them. You can decompile your DLL with ILSpy to exam that these are indeed now common Resources under the Resources folder.
So how can you do this in your new project? Replicate the exact method you did in your first one - add ToolsSilverlight.dll, list your items as Embedded Resource, and call them using EmbeddedResourceFileReader.ReadFile. You may also want to ensure your .csproj file <ItemGroup/> structure is similar to original one. Not sure if <None Include="Properties\AppManifest.xml"/> is needed by EmbeddedResourceFileReader, but it may be.
We have a ad-hoc reporting projecto where we created several data source views (DSV) and several Report Models (SDML). Frequently we need to change the DSV associated to a particular SDML, but we only found it's reference in one place: the "Data Source View Name" property (availabe through the VS properties pane) of the sdml file.
We found absolutly no reference to it anywhere else, not even in the sdml xml code view. But, strangly enough, VS asks to check out the sdml file when we change that "Data Source View Name" property ... then makes no change to the checked out file.
Finally, when we close the project and reopen it, VS forgets that property setting. This behavior points to some kind of in-memory-only saving location for that setting ...
Are we missing something or does anybody noticed similar behavior?
Thanks.
Bruno Lopes
Look in your ReportModel.smdlproj file (the project file).
View it in notepad rather than double-click, as that will just launch Visual Studio.
In the <Models> section you'll find:
<Models>
<ModelProjectItem>
<Name>MySmdlName.smdl</Name>
<FullPath>MySmdlName.smdl</FullPath>
<DsvName>MyDsvName</DsvName>
</ModelProjectItem>
</Models>
This is how VS associates the dsv and the smdl files.
Why this association is getting lost when you deploy I don't know, but this may help.
You are right. I do not know if it is by design or anything else but you can try doing this:
After deploying smdl's to the Report Server, click on Edit in the Model Definition section for a smdl. This downloads the smdl and the xml seems to have the DataSourceView element in it!