locked
WinRT does not support #using of a managed assembly

    Question

  • Hello I am trying to read text from .txt file and print it to textbox, but I cant... It stops at marshal_as... This is Visual Studio 2013 -> Windows Store application

    error C1114: 'c:\windows\microsoft.net\framework\v4.0.30319\mscorlib.dll' : WinRT does not support #using of a managed assembly
    2 IntelliSense: an ordinary pointer to a C++/CX mapping ref class or interface class is not allowed

    If anyone know how to fix this or any other method for reading .txt file please tell me... 

    	

    using namespace std;

    ifstream infile("test.txt"); String^ mystring; std::string line; if (infile.is_open()) { getline(infile, line); textbox1->Text = msclr::interop::marshal_as<String^>(mystring); infile.close(); }



    • Edited by -Stealth- Monday, October 21, 2013 5:56 PM
    Monday, October 21, 2013 5:56 PM

Answers

  • These lines are the problem:

    StorageFile^ file;
     file->GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"));

    It will crash since file is unset. You cannot callthrough an uninitialized pointer. You need to call StorageFile::GetFileFromApplicationUriAsyncas a task to get file as the return.

    create_task(StorageFile::GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"))).then([this](IStorageFile^ file)
     {
        // use the file
     }


    --Rob

     


    Wednesday, October 23, 2013 9:11 PM
    Owner

All replies

  • C++/Cx is not a managed language and so cannot directly call managed assemblies. If your managed assembly is valid for Windows Store apps you can wrap it in a Windows Runtime Component and reference the component instead
    Monday, October 21, 2013 6:36 PM
    Owner
  • How can I do that??? 
    Monday, October 21, 2013 6:38 PM
  • I'm on my phone and can't get a link, but you should be able to find it by searching for "Windows Runtime Componeny" in the search box at the top right of the page. Also check out the App Architecture links.
    Monday, October 21, 2013 6:47 PM
    Owner
  • Is there any other function that would to the same job??? Basically I just want to take few numbers from .txt file and show it in textblock... 
    Monday, October 21, 2013 7:37 PM
  • Yes, you can use the Windows Runtime API to read from the file. See Read or write file data and the File access sample .

    --Rob

    Monday, October 21, 2013 8:12 PM
    Owner
  • Hey, thank you for help. I tried File access sample and got rid of errors, but it won't show text in textblock. What I am doing wrong??? It won't display if statment nor else statement comment

    	StorageFile^ file;
    	file->GetFileFromPathAsync("C:\\Users\\Administrator\\Desktop\\test.txt");
    
    	if (file != nullptr)
    	{
    		String^ userContent;
    		if (userContent != nullptr && !userContent->IsEmpty())
    		{
    			create_task(FileIO::WriteTextAsync(file, userContent)).then([this, file, userContent](task<void> task)
    			{
    				
    				try
    				{
    					task.get();
    					textblock1->Text = "The following text was written to '" + file->Name + "':\n\n" + userContent;
    				}
    				catch (COMException^ ex)
    				{
    					
    				}
    			});
    		}
    		else
    		{
    			textblock1->Text = "The text box is empty, please write something and then click 'Write' again.";
    		}
    	}



    • Edited by -Stealth- Tuesday, October 22, 2013 6:49 AM
    Tuesday, October 22, 2013 6:44 AM
  • Hey, I tried with example 5 and used code below... This one executes else statement and print "Does not exist"... I think something is wrong with path or file != nullptr in if statement... But still don't know how to fix it...

    	StorageFile^ file;
    	file->GetFileFromPathAsync(L"C:\\Users\Administrator\\Desktop\\test.txt");
    
    	if (file != nullptr)
    	{
    		create_task(file->OpenAsync(FileAccessMode::Read)).then([this, file](task<IRandomAccessStream^> task)
    		{
    			try
    			{
    				IRandomAccessStream^ readStream = task.get();
    				UINT64 const size = readStream->Size;
    				if (size <= MAXUINT32)
    				{
    					DataReader^ dataReader = ref new DataReader(readStream);
    					create_task(dataReader->LoadAsync(static_cast<UINT32>(size))).then([this, file, dataReader](unsigned int numBytesLoaded)
    					{
    						String^ fileContent = dataReader->ReadString(numBytesLoaded);
    						delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed.
    						textblock1->Text = "The following text was read from '" + file->Name + "' using a stream:\n\n" + fileContent;
    					});
    				}
    				else
    				{
    					delete readStream; // As a best practice, explicitly close the readStream resource as soon as it is no longer needed.
    					textblock1->Text = "File " + file->Name + " is too big for LoadAsync to load in a single chunk. Files larger than 4GB need to be broken into multiple chunks to be loaded by LoadAsync.";
    				}
    			}
    			catch (COMException^ ex)
    			{
    				//rootPage->HandleFileNotFoundException(ex);
    			}
    		});
    	}
    	else
    	{
    		textblock1->Text = "Does not exist";
    	}

    Tuesday, October 22, 2013 1:37 PM
  • Your app doesn't have permission to read from the desktop. You can read files outside of the app's install and data directories only with user permission, either through declared capabilities or explicitly from the file picker.

    See my blog entry Skip the path: stick to the StorageFile for more discussion on this.

    --Rob

    Tuesday, October 22, 2013 3:00 PM
    Owner
  • I placed test.txt into app folder but it still don't work... 

    This line is executed, it skip if statement for some reason...

    else
    	{
    		textblock1->Text = "Does not exist";
    	}



    I also tried to "force" if statement to execute using if (5 != 3), but then app crashed... 

    if (file != nullptr) is always false and I don't know why... 

    I placed test.txt in all possible folders within app folder and used 

    file->GetFileFromPathAsync(L"test.txt");


    • Edited by -Stealth- Tuesday, October 22, 2013 3:52 PM
    Tuesday, October 22, 2013 3:39 PM
  • You need to provide the full path. I'd recommend using GetFileFromApplicationUriAsync instead of GetFileFromPathAsync:

    file->GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"));

    The ms-appx protocol will find the file in the app's install directory. See URI schemes for the available options.

    --Rob
    Tuesday, October 22, 2013 11:05 PM
    Owner
  • Tried that and same result... Else statement is executed, when I force if statement to execute app crashes... 

    	StorageFile^ file;
    	file->GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"));


    Here is full code

    void wei::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	StorageFile^ file;
    	file->GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"));
    	if (file != nullptr)
    	{
    		create_task(file->OpenAsync(FileAccessMode::Read)).then([this, file](task<IRandomAccessStream^> task)
    		{
    			try
    			{
    				IRandomAccessStream^ readStream = task.get();
    				UINT64 const size = readStream->Size;
    				if (size <= MAXUINT32)
    				{
    					DataReader^ dataReader = ref new DataReader(readStream);
    					create_task(dataReader->LoadAsync(static_cast<UINT32>(size))).then([this, file, dataReader](unsigned int numBytesLoaded)
    					{
    						String^ fileContent = dataReader->ReadString(numBytesLoaded);
    						delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed.
    						textblock1->Text = "The following text was read from '" + file->Name + "' using a stream:\n\n" + fileContent;
    					});
    				}
    				else
    				{
    					delete readStream; // As a best practice, explicitly close the readStream resource as soon as it is no longer needed.
    					textblock1->Text = "File " + file->Name + " is too big for LoadAsync to load in a single chunk. Files larger than 4GB need to be broken into multiple chunks to be loaded by LoadAsync.";
    				}
    			}
    			catch (COMException^ ex)
    			{
    				//rootPage->HandleFileNotFoundException(ex);
    			}
    		});
    	}
    	else
    	{
    		textblock1->Text = "Does not exist";
    	}
    }

    • Edited by -Stealth- Wednesday, October 23, 2013 4:01 PM
    Wednesday, October 23, 2013 2:23 PM
  • In VS 2013, in Solution Explorer, first make sure that the "test.txt" file is included in the project. Then, in Solution Explorer, right-click on test.txt and choose "Properties". In the text.txt properties, change the Configuration to "All Configurations" and the Platform to "All Platforms", then for "Content" make sure it is "Yes" and for "Item Type" make sure it is "Text" ("Excluded From Build" should be either blank or set to "No". Click on Apply then click on OK.

    Now Rebuild the project in "Debug" configuration for "Win32" (you can set these either from the drop down menus in the toolbar area or by choosing "Configuration Manager" from the "BUILD" menu). When that is done, open up the root folder of the solution (where the .sln file is). There should be a folder there called "Debug". Open that. Inside "Debug" should be a folder with the name of your app. Open that folder and then open the folder called "AppX" that is inside the app folder. Verify that "test.txt" is there (this should be the same folder that the .exe file for your app is in so if you don't see your app's exe then you need to make sure your project was successfully built and then try "Rebuild Solution" in the "BUILD" menu).

    Try running your app now. It should work. If not, try going to the Start Screen, finding your app in the All Apps section, right clicking it, and uninstalling it. Then go back to Visual Studio and try debugging it again so that it deploys the updated version. That should work. If not, make sure you followed all the steps above and if so, report back.


    Visual C++ MVP | Website | Blog | @mikebmcl | Windows Store DirectX Game Template

    Wednesday, October 23, 2013 5:33 PM
  • Like Mike says, make sure that the text.txt file is actually getting packaged and installed with the app. It needs to be marked as Content and to copy to the output directory. Check for it in the created appxpackage to make sure it's there. Look for a directory %project%\bin\debug\Appx

    --Rob

    Wednesday, October 23, 2013 6:10 PM
    Owner
  • Hey... I tried all steps above and it's still same... This line executes... Here is link to project... http://sdrv.ms/19w8LX5
    textblock1->Text = "Does not exist";
    Wednesday, October 23, 2013 7:43 PM
  • These lines are the problem:

    StorageFile^ file;
     file->GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"));

    It will crash since file is unset. You cannot callthrough an uninitialized pointer. You need to call StorageFile::GetFileFromApplicationUriAsyncas a task to get file as the return.

    create_task(StorageFile::GetFileFromApplicationUriAsync(ref new Uri("ms-appx:///test.txt"))).then([this](IStorageFile^ file)
     {
        // use the file
     }


    --Rob

     


    Wednesday, October 23, 2013 9:11 PM
    Owner
  • Thank you sooo much... I finally solved my problem... 

    But I still have some questions :)

    1. How is copy/paste working with Windows Store apps... I would like to read a text outside of app folder but because of restrictions I can't... So I tought maybe I could copy file which is outside of app folder and paste it into app folder and then read it... Is that possible or there are restrictions about that as well???

    2. Can I GetFile even if I don't know the full name of that file??? That file is made of date.filename... Date = is changing, filename = is permanent... So could I somehow set it to find just part of the file name and open it??? To search only for filename??? Example: 25-10-2013.myfile.txt   -> Can I make it somehow recognize file only by myfile.txt and open/read/copy it??? 

    Friday, October 25, 2013 8:28 PM
  • 1. I'm not sure what you mean. Copy/Paste is a user gesture that isn't available to apps. Can you create a new thread for the new topic and explain what you mean in more detail? If you mean to programmatically copy a file from one directory to another then you can do that with StorageFile::CopyAsync(IStorageFolder) so long a the app has appropriate permissions to read the original file and to write to the target folder.

    2. Not directly. You could query the file names and then examine the results to find the one you want, then open that file.

    --Rob

    Friday, October 25, 2013 9:11 PM
    Owner
  • 1. "If you mean to programmatically copy a file from one directory to another then you can do that with StorageFile::CopyAsync(IStorageFolder)" - Ye that...

    2. I found solution for that...



    • Edited by -Stealth- Sunday, October 27, 2013 8:16 AM
    Saturday, October 26, 2013 11:15 AM